我的编译器是最新的VC++ 2013 RC。
int f(bool b)
{
return {}; // OK
return b ? 1 : { }; // C2059: syntax error : '{'
return b ? 1 : {0}; // C2059: syntax error : '{'
return b ? {1} : {0}; // C2059: syntax error : '{'
}
为什么花括号初始化列表不能用在三元运算符中?
此行为是 C++ 标准定义为格式错误,还是只是 VC++ 编译器的错误?
好吧,这是标准关于花括号初始化列表 (8.5.3.1) 的规定:
列表初始化 可以用
- 作为变量定义中的初始化器 (8.5)
- 作为新表达式中的初始化器 (5.3.4)
- 在返回语句中(6.6.3)
- 作为函数参数 (5.2.2)
- 作为下标 (5.2.1)
- 作为构造函数调用的参数 (8.5, 5.2.3)
- 作为非静态数据成员的初始值设定项 (9.2)
- 在内存初始化器中(12.6.2)
- 在作业的右侧 (5.17)
由于这没有提到条件运算符,我猜你的编译器是对的。另请注意,条件运算符需要
:
(5.16) 两侧的表达式,据我所知,大括号初始化器不是表达式。
这是一个语法错误。大括号初始化列表不是表达式,并且它没有类型或值类别。 braced-init-list 可在 C++ 语法中的多个位置使用,并且条件表达式的操作数不是这些位置之一。因此你的代码甚至无法解析。
如果你想这样做:
struct T { ... };
T f(bool b)
{
return b ? {i,j,k} : {x,y};
}
相反,你可以这样做:
T f(bool b)
{
return b ? T{i,j,k} : T{x,y};
}
我相信,虽然这需要一个移动构造函数,但它不会使用它并且 RVO 会启动。
或者你当然可以这样做:
T f(bool b)
{
if (b)
return {i,j,k};
else
return {x,y};
}
获得列表初始化的所有优点。