vso*_*tco 9 c++ decltype sfinae c++11
我最近看到一些基于SFINAE的代码如下所示:
template <typename T>
auto test(T &myclass) -> decltype(myclass.f(), void())
{
// do something here, don't return anything (void)
}
Run Code Online (Sandbox Code Playgroud)
基本上上面的函数使用SFINAE来拒绝所有T没有f()作为成员函数的类型的参数.SFINAE发生在decltype我们有两个用逗号运算符分隔的表达式的地方.如果无法评估第一个表达式,SFINAE会启动并拒绝过载.如果可以计算表达式,那么,由于逗号运算符,void正在从函数返回.
据我明白,void()"构建体"一个void处于未评估上下文对象(是的,这是合法的),然后由所拾取decltype所以void是该函数的返回类型.
我的问题是:为什么我们不能使用void{}呢?它是否具有void在未评估的上下文中"构造" 对象的相同效果?我的编译器(g ++/clang ++)不接受void{}代码
error: compound literal of non-object type 'void'(克++ 4.9 /克++ 5)
和
error: illegal initializer type 'void'(clang ++ 3.5)
这是一种表达方式.[expr.type.conv]/P2-3:
表达式
T(),其中,T是一种简单类型说明符或 类型名称说明符用于非阵列的完整对象类型或(可能CV-合格)void类型,创建指定类型的prvalue,是一种通过产生其值值初始化(8.5)类型的对象T; 没有为该void()情况进行初始化 .[ 注意:...... - 结束说明 ]类似地,一个简单型说明符或类型名称说明符后跟一个 支撑-INIT列表创建指定类型的临时对象 直接列表初始化与指定的(8.5.4)支撑-INIT列表,其值是临时对象作为prvalue.
您无法创建类型的临时对象void.void()是一个特殊的例外,允许你制作一个voidprvalue.