为什么我必须用括号表示逗号表达式的初始化表达式?

时间:2016-02-04 17:28:29

标签: c++ initialization comma-operator

煮沸一个问题我已经了解它的本质,我可以通过首先在逗号表达式中执行do-nothing lambda来将变量初始化为int:

int main(){
  auto x = ( []{}(), 10 );          // same effect as auto x = 10;
}

但如果我没有将初始化表达式括起来,

int main(){
  auto y = []{}(), 10;              // won't compile
}

所有gcc,clang和MSVC都抱怨尝试使用y表达式初始化void

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

1 个答案:

答案 0 :(得分:5)

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

int i = 2, j = 3;     // OK: declares `i` and `j`
int i = 2, 3;         // Error: `3` is not a declarator

在第二种情况下,它看起来很模糊。是,分隔声明符,还是表达式,的{​​{1}}部分?

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

  

简单的声明:
   decl-specifier-seq opt init-declarator-list opt 2, 3
   attribute-specifier-seq decl-specifier-seq opt init-declarator-list ;

     

初始化声明符列表:
  初始化声明符
   init-declarator-list ; init-declarator

     

初始化声明符:
  声明初始值设定项 opt

语法的工作方式,这意味着在解析声明时,会考虑与 init-declarator , 匹配的最长序列。 (这有时被称为“最大咀嚼原则”)。因此,匹配 init-declarator int i = 2, 。然后,无法匹配3,因此解析失败。