work around GCC 6~11 ADL bug

see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51577
ADL seems to work properly when we do the SFINAE check via the return type, but not when using a dummy template parameter

fix #3992
This commit is contained in:
Paul Groke 2022-09-15 13:36:49 +02:00
parent 9080381758
commit 096014a45d

View File

@ -205,12 +205,13 @@ struct StreamPrinter {
// Don't accept member pointers here. We'd print them via implicit // Don't accept member pointers here. We'd print them via implicit
// conversion to bool, which isn't useful. // conversion to bool, which isn't useful.
typename = typename std::enable_if< typename = typename std::enable_if<
!std::is_member_pointer<T>::value>::type, !std::is_member_pointer<T>::value>::type>
// Only accept types for which we can find a streaming operator via // Only accept types for which we can find a streaming operator via
// ADL (possibly involving implicit conversions). // ADL (possibly involving implicit conversions).
typename = decltype(std::declval<std::ostream&>() // (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
<< std::declval<const T&>())> // lookup properly when we do it in the template parameter list.)
static void PrintValue(const T& value, ::std::ostream* os) { static auto PrintValue(const T& value, ::std::ostream* os)
-> decltype((void)(*os << value)) {
// Call streaming operator found by ADL, possibly with implicit conversions // Call streaming operator found by ADL, possibly with implicit conversions
// of the arguments. // of the arguments.
*os << value; *os << value;