【发布时间】:2015-02-24 05:06:58
【问题描述】:
我最近看到一些基于 SFINAE 的代码如下所示:
template <typename T>
auto test(T &myclass) -> decltype(myclass.f(), void())
{
// do something here, don't return anything (void)
}
基本上,上面的函数使用 SFINAE 拒绝所有类型为 T 且没有 f() 作为成员函数的参数。 SFINAE 发生在decltype 中,其中我们有 2 个由逗号运算符分隔的表达式。如果无法计算第一个表达式,SFINAE 将启动并拒绝重载。如果可以计算表达式,那么由于逗号运算符的存在,函数会返回 void。
据我了解,void() 在未评估的上下文中“构造”void 对象(是的,这是合法的),然后由decltype 选择,所以void 是返回函数的类型。
我的问题是:为什么我们不能使用 void{} 来代替? 在未评估的上下文中“构造”void 对象的效果不一样吗?我的编译器 (g++/clang++) 不接受 void{} 代码
error: compound literal of non-object type 'void'(g++4.9/g++5)
和
error: illegal initializer type 'void'(clang++ 3.5)
【问题讨论】:
-
是函数声明吗?我认为不能在
decltype中使用函数声明,而只能使用函数名称,但我可能又被最令人烦恼的解析所困扰;) 3 分钟后:我实际上很确定它不是 MVP,因为decltype(int(int)) x;被拒绝,但decltype(int()) x;有效,x的类型为int。