C++ 为什么必须在初始化表达式中插入';是逗号表达式吗?

C++ 为什么必须在初始化表达式中插入';是逗号表达式吗?,c++,initialization,comma-operator,C++,Initialization,Comma Operator,把问题归结到本质上,我可以通过在逗号表达式中首先执行不执行任何操作的lambda将变量初始化为int,如下所示: int main(){ auto x = ( []{}(), 10 ); // same effect as auto x = 10; } 但是如果我不把初始化表达式括起来 int main(){ auto y = []{}(), 10; // won't compile } gcc、clang和MSVC都抱怨试图用void表达

把问题归结到本质上,我可以通过在逗号表达式中首先执行不执行任何操作的lambda将变量初始化为int,如下所示:

int main(){
  auto x = ( []{}(), 10 );          // same effect as auto x = 10;
}
但是如果我不把初始化表达式括起来

int main(){
  auto y = []{}(), 10;              // won't compile
}
gcc、clang和MSVC都抱怨试图用
void
表达式初始化
y


为什么我必须用括号括住逗号表达式以将其用作初始值设定项?

在声明中,
符号分隔声明符。一个简单的例子:

int i = 2, j = 3;     // OK: declares `i` and `j`
int i = 2, 3;         // Error: `3` is not a declarator
在第二种情况下,它看起来模棱两可。是分隔声明符的
还是表达式的
部分
2,3

要解决这种歧义,我们可以参考语言语法(C++14[dcl.decl]):

简单声明:
decl说明符seqopt init声明符listopt

属性说明符seq decl说明符seqopt init声明符list

初始化声明器列表:
初始化声明器
初始化声明器列表
初始化声明器

初始化声明器:
声明器初始化器


按照语法的工作方式,这意味着在解析声明时要考虑与init声明符
匹配的最长可能序列。(这有时被称为“最大咀嚼原则”)。所以
inti=2,
匹配init声明符
。然后,
3
无法匹配
init声明符
,因此解析失败。

“解决了一个我遇到的问题…”听起来像是有问题。在实际初始化
x
之前,是否需要lambda表达式的副作用?是的。在计算要在成员初始化列表中用于初始化类数据成员的表达式之前,我想执行一个静态断言。我认为实际上没有必要将其放入lambda表达式中。我需要在初始化表达式之前对static_断言求值,因为如果static_断言失败,初始化表达式将导致非常可怕的模板实例化错误消息。静态_断言的目的是生成一个好的错误消息?更清楚。