32

我的编译器是最新的 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++ 编译器的错误?

4

2 回答 2

21

好吧,这就是标准对braced-init-list (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)
  • 在 mem-initializer (12.6.2) 中
  • 在作业的右侧(5.17)

由于这没有提到条件运算符,我猜你的编译器是对的。另请注意,条件运算符需要(5.16)两边的表达式,:据我了解,大括号初始化器不是表达式。

于 2013-09-17T07:07:30.787 回答
7

这是一个语法错误。大括号初始化列表不是表达式,它没有类型或值类别。括号初始化列表在 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};
}

获得列表初始化的所有优点。

于 2013-09-17T08:22:45.363 回答