结构化绑定初始值设定项表单 { 赋值表达式 } 对于 clang 上的数组类型失败

Structured binding initializer form { assignment-expression } fails for array type on clang

本文关键字:clang 对于 表达式 失败 类型 数组 赋值 绑定 表单 结构化      更新时间:2023-10-16

[dcl.dcl]/1(最终C++17草案,N4659(将简单声明的语法描述为:

[...]

简单声明: - [...] - 属性说明符-seq(opt(decl-specifier-seq ref-qualifier(opt([标识符列表]初始值设定项;

[dcl.dcl]/8 描述了简单声明的后一种形式是结构化绑定声明

带有标识符列表简单声明称为结构化绑定声明([dcl.struct.bind](。decl-specifier-seq应仅包含类型说明符autocv-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 } ;