为什么我必须用括号括起来初始化表达式(逗号表达式)?

Why do I have to parenthesize an initializing expression that's a comma expression?

本文关键字:表达式 初始化 为什么 起来      更新时间:2023-10-16

归结我遇到的问题,我可以通过将变量初始化为 int,方法是首先在逗号表达式中执行一个无所事事的 lambda,如下所示:

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-specifier-seq opt init-declarator-listopt
;    attribute-specifier-seq decl-specifier-seqopt init-declarator-list ;

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

初始化声明器:
    声明符初始值设定项选项

语法的工作方式,这意味着在解析声明时,会考虑与 init 声明符,匹配的最长可能序列。(这有时被称为"最大咀嚼原则"(。 所以int i = 2,匹配初始化声明器, .然后3无法匹配init-declarator,因此解析失败。