三元运算符中为啥不能使用braced-init-list?
Posted
技术标签:
【中文标题】三元运算符中为啥不能使用braced-init-list?【英文标题】:Why can braced-init-list not be used in ternary operator?三元运算符中为什么不能使用braced-init-list? 【发布时间】:2013-09-21 11:43:15 【问题描述】:我的编译器是最新的 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 : ''
为什么三元运算符中不能使用braced-init-list?
这种行为是否被 C++ 标准定义为格式错误,还是只是 VC++ 编译器的错误?
【问题讨论】:
不是表达式,这里检查语法Conditional operator differences between C
and C++
据我所知,通过统一初始化应该可以做到return b ? 0 : 1
。
@Rapptz,返回 b ? 0 : 1 也被拒绝。
@xmllmx 是的,你是对的。它不适用于内置类型。
语法错误是由于?:
运算符而不是因为return
,所以考虑条件运算符的语法。而表达式是“指定计算的一系列运算符和操作数”(这是 C++ 标准中给出的定义)
【参考方案1】:
嗯,这就是标准对括号初始化列表 (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) 两边的表达式,据我了解,大括号初始化器不是表达式。
【讨论】:
【参考方案2】:这是一个语法错误。大括号初始化列表不是表达式,它没有类型或值类别。括号初始化列表在 C++ 语法中的不同位置可用,条件表达式的操作数不是这些位置之一。因此,您的代码甚至无法解析。
如果你想这样做:
struct T ... ;
T f(bool b)
return b ? i,j,k : x,y;
您可以这样做:
T f(bool b)
return b ? Ti,j,k : Tx,y;
而且我相信,虽然这需要一个移动构造函数,但它不会使用它并且 RVO 会启动。
当然,您也可以这样做:
T f(bool b)
if (b)
return i,j,k;
else
return x,y;
获得列表初始化的所有优点。
【讨论】:
如果 T 没有接受这些参数的构造函数,T(i,j,k)
将不起作用。 Ti,j,k
没问题以上是关于三元运算符中为啥不能使用braced-init-list?的主要内容,如果未能解决你的问题,请参考以下文章
如果在三元运算符中使用局部变量,为啥从 int 到 short 的缩小转换不起作用