[dcl.dcl]/1(最终C++17草案,N4659(将简单声明的语法描述为:
[...]
简单声明: - [...] - 属性说明符-seq(opt(decl-specifier-seq ref-qualifier(opt([标识符列表]初始值设定项;
[dcl.dcl]/8 描述了简单声明的后一种形式是结构化绑定声明:
带有标识符列表的简单声明称为结构化绑定声明([dcl.struct.bind](。decl-specifier-seq应仅包含类型说明符
auto
和cv-qualifier:s。初始值设定项的格式应为"=赋值表达式",形式为"{赋值表达式}",或形式为"(赋值表达式(",其中赋值表达式是数组或非联合类类型。
即,出于此问题的目的,结构化绑定具有简化的语法:
auto
[标识符列表]初始值设定项;
其中以下任何形式是有效的初始值设定项:s:
... =赋值表达式
。{赋值表达式}
。(赋值表达式(
因此,可以说以下代码的格式正确:
struct S { int s; };
int main() {
const S s{42};
const int arr[1] = {42};
// ... of the form “= assignment-expression”
auto[s_form1] = s;
auto[e_form1] = arr;
// ... of the form “{ assignment-expression }”
auto[s_form2]{s};
auto[e_form2]{arr};
// ... of the form “( assignment-expression )”
auto[s_form3](s);
auto[e_form3](arr);
(void)s_form1; (void)s_form2; (void)s_form3;
(void)e_form1; (void)e_form2; (void)e_form3;
return 0;
}
使用-std=c++17
和-std=c++2a
,GCC(9.3(接受此代码,而clang(10.0.0以及HEAD/11(拒绝数组的">{赋值表达式}"形式:
auto[e_form2]{arr}; ^~~ error: cannot initialize an array element of type 'const int' with an lvalue of type 'const int [1]'
对于右值数组,它同样失败:
using SingleElementIntArray = int[1]; auto[e_form2]{SingleElementIntArray{42}}; ^~~~~~~~~~~~~~~~~~~~~~~~~ error: cannot initialize an array element of type 'int' with an rvalue of type 'SingleElementIntArray' (aka 'int [1]')
问题
- 谁就在这里,海湾合作委员会还是叮当声?我的猜测是海湾合作委员会;如果是这样,这是一个已知的叮当虫吗?
这是一个已知的错误,有一个开放的错误报告
LLVM 打开错误报告:
- 错误 32466 - Clang 不支持数组初始值设定项形式 {" expr }" 的结构化绑定
Ryou Ezoe 2017-03-30 00:24:07 PDT:
Clang 不支持初始值设定项表单 {" expr 的结构化绑定 }",如果 expr 是数组对象的 id-表达式。 叮当不接受 以下代码。
int expr[] = { 1,2,3 } ; auto [a,b,c]{expr} ;
出现错误:
prog.cc:4:18:错误:无法初始化数组 类型为"int"的元素,左值为"int [3]">
其他情况按预期工作。"( expr (" 以及 "{ expr }",其中 expr 是类对象的 id 表达式:
auto [a,b,c](expr) ; struct X { int x,y,z } ; X x {1,2,3} ; auto [a,b,c]{ x } ;