为什么在这种情况下 decltype 行为不同于 libstdc++ 的正常表达式?
Why in this case decltype behavior is different from normal expression with libstdc++?
我发现 decltype
内的表达式处理成功而 decltype
外的相同表达式给出错误的情况:see on Godbolt.
我正在检查给定类型 (operator <<
) 是否存在输出到流的过载 - 通过使用 decltype
和类型特征。但是对于来自 GCC < 7 decltype
returns 的 libstdc++,即使在没有这种重载的情况下也是正确的类型。
我用 libc++ 尝试了 Clang - 没有这样的问题。尝试过 GCC 7.1 - 没问题。但是,如果我尝试使用 GCC < 7 或 Clang 和来自 GCC < 7 的 libstdc++,就会出现问题。
基本上:
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)
那么,为什么会这样,libstdc++ 有什么问题?
std::declval<std::ostringstream&>() << std::declval<T const &>()
// ^ ^^^^^^^^
价值类别很重要。您正在测试将 const T
左值流式传输到 ostringstream
左值的能力。
在您的原始代码中,<<
解析为右值流的 until-recently-unconstrained <<
重载。没有约束,表达式总是合式的。
我发现 decltype
内的表达式处理成功而 decltype
外的相同表达式给出错误的情况:see on Godbolt.
我正在检查给定类型 (operator <<
) 是否存在输出到流的过载 - 通过使用 decltype
和类型特征。但是对于来自 GCC < 7 decltype
returns 的 libstdc++,即使在没有这种重载的情况下也是正确的类型。
我用 libc++ 尝试了 Clang - 没有这样的问题。尝试过 GCC 7.1 - 没问题。但是,如果我尝试使用 GCC < 7 或 Clang 和来自 GCC < 7 的 libstdc++,就会出现问题。
基本上:
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)
那么,为什么会这样,libstdc++ 有什么问题?
std::declval<std::ostringstream&>() << std::declval<T const &>()
// ^ ^^^^^^^^
价值类别很重要。您正在测试将 const T
左值流式传输到 ostringstream
左值的能力。
在您的原始代码中,<<
解析为右值流的 until-recently-unconstrained <<
重载。没有约束,表达式总是合式的。