为什么我们不能在未评估的上下文中使用大括号初始值设定项?

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)

T.C*_*.C. 8

这是一种表达方式.[expr.type.conv]/P2-3:

表达式T(),其中,T是一种简单类型说明符类型名称说明符用于非阵列的完整对象类型或(可能CV-合格)void类型,创建指定类型的prvalue,是一种通过产生其值值初始化(8.5)类型的对象T; 没有为该void()情况进行初始化 .[ 注意:...... - 结束说明 ]

类似地,一个简单型说明符类型名称说明符后跟一个 支撑-INIT列表创建指定类型的临时对象 直接列表初始化与指定的(8.5.4)支撑-INIT列表,其值是临时对象作为prvalue.

您无法创建类型的临时对象void.void()是一个特殊的例外,允许你制作一个voidprvalue.