Reputation: 593
I found a case when expression inside decltype
is processed successfully while the same expression outside decltype
gives an error: see on Godbolt.
I'm checking if there is an overload of outputting into stream for a given type (operator <<
) - by using decltype
and type traits. But for libstdc++ from GCC < 7 decltype
returns a correct type even for cases where there isn't such overload.
I tried Clang with libc++ - there is no such problem. Tried GCC 7.1 - no problem. But if I try GCC < 7 or Clang with libstdc++ from GCC < 7 - problem arise.
Basically:
class Foo {};
...
decltype(std::declval<std::ostringstream>() << std::declval<Foo>()) // gives std::ostringstream&
...
Foo foo;
std::ostringstream out;
out << foo; // gives an error (as it should, there is no overload for Foo)
So, why it's happening, what's wrong with libstdc++?
Upvotes: 0
Views: 74
Reputation: 137301
std::declval<std::ostringstream&>() << std::declval<T const &>()
// ^ ^^^^^^^^
Value categories matter. You are testing for the ability to stream a const T
lvalue into a ostringstream
lvalue.
In your original code, the <<
resolves to the until-recently-unconstrained <<
overload for rvalue streams. Without the constraint, the expression is always well-formed.
Upvotes: 2