【发布时间】:2016-05-27 10:13:35
【问题描述】:
我正在尝试创建一个类型特征类以确定特定类型 T 是否可以通过 std::ostream 的 << 运算符进行流式传输。我使用的是简单的 SFINAE 技术。
最终,我尝试评估替换失败的表达式是:
decltype(std::declval<std::ostream>() << std::declval<T>()) ;
我的期望是,给定一个T 类型的实例t 和一个std::ostream 实例os,如果表达式os << t 格式不正确,那么应该会发生替换失败。
但显然,无论T 类型如何,这里都不会发生替换失败。即使我只是使用上面的decltype 表达式声明了一个typedef,在SFINAE 的上下文之外,它也会愉快地编译,即使T 不能与std::ostream 一起使用。
例如:
struct Foo { };
int main()
{
// This compiles fine using GCC 4.9.2
//
typedef decltype(
std::declval<std::ostream>() << std::declval<Foo>()
) foo_type;
}
上面的代码使用 GCC 4.9.2 可以很好地编译,这不是我所期望的,因为 << 运算符没有重载以使用类型 Foo。当然,如果我说:
std::cout << Foo();
... 我得到一个编译器错误。那么为什么上面的decltype 表达式甚至可以编译呢?
【问题讨论】:
-
它与
std::declval<std::ostream&>()正确反应。但我不知道为什么。