C++ 列表对未知大小数组的引用的初始化:是否应该推断数组大小?

C++ 列表对未知大小数组的引用的初始化:是否应该推断数组大小?,c++,arrays,reference,list-initialization,C++,Arrays,Reference,List Initialization,下面的代码编译得很好,并输出int[3]array的大小 #include <iostream> int main() { const int (&a)[] = { 1, 2, 3 }; std::cout << sizeof a << std::endl; } #包括 int main() { 常量int(&a)[]={1,2,3}; 标准在这一点上并不完全清楚,我认为GCC的解释可能是WG21的意图,但我不确定 该标准的相关部分是[dc

下面的代码编译得很好,并输出
int[3]
array的大小

#include <iostream>

int main()
{
  const int (&a)[] = { 1, 2, 3 };
  std::cout << sizeof a << std::endl;
}
#包括
int main()
{
常量int(&a)[]={1,2,3};

标准在这一点上并不完全清楚,我认为GCC的解释可能是WG21的意图,但我不确定

该标准的相关部分是[dcl.array],它描述了如何确定由声明器声明的类型,其中声明器包含数组形成运算符
[]
。我引用了相关部分:

当声明符后面跟一个初始值设定项(11.6)或静态数据成员的声明符后面跟一个大括号或相等的初始值设定项(12.2)时,也可以省略数组绑定。在这两种情况下,绑定都是根据提供的初始元素数(例如,
N
)计算的(11.6.1),并且
D
的标识符的类型是“N
T
的数组”

这不仅适用于数组本身的声明,也不完全适用于数组引用的情况,因为在解释[dcl.ref](描述
&
&
运算符)时必须递归地引用[dcl.array]但是,我认为后一种解释应该被拒绝,因为我们不希望初始化器导致一个绑定的推导,当<代码> []/COD>被埋没在声明器中时。
int (*a[1])(const int (&)[]) = {0};
在这里GCC和Clang,我认为常识也同意,
a
的类型是
int(*[1])(const int(&)[])
,而不是
int(*[1])(const int(&)[1])
:事实上
a
拥有一个初始值设定项并不会导致内部数组绑定被推导出来


基于此,我认为GCC在不推断代码中的数组绑定方面是正确的,因此
a
具有type
const int(&[]

是否
const int(&a)[]=…
甚至有效?该标准指定了可以忽略边界的情况()但这只适用于数组本身,而不适用于数组引用。@Daniel Langr:链接中的文本说:“除了允许使用不完整对象类型的声明外,还可以省略数组绑定…”这实际上是一个声明,其中不允许类型:C++中的不完整类型的引用是OK。在开始时,未知绑定数组已经作为C++中的不完整类型出现。尽管在这个上下文中它是否应该保持不完整,但目前还不清楚。因此,问题是:说明:。因此它不允许引用类型(尽管我不确定这是有意的)。@geza:嗯……不。您引用的措辞指的是上述“附加”情况,即在我上面引用的部分之后描述的情况。它与上述“允许不完整对象类型的声明”没有任何关联并且没有以任何方式禁止它们。这里的措辞非常清楚。@AnT:我可能误解了你,或者是标准。下面是完整的句子:。这里不是这样吗?边界是从初始值设定项计算出来的。所谓“允许不完全类型”,是不是指像“extern Foo a[];”(Foo在这里可能是不完整的)?在您的情况下,声明的类型必须是完整的,因为它是一个定义(据我所知,对不完整类型的引用是一个完整的类型)。您能阅读问题下的注释吗?是不是这样,
const int(&a)[]=…
格式不正确?因为他们说:,所以不允许引用数组。@geza:你似乎自相矛盾。在你最近的评论中,你似乎建议9.2.3.4只适用于数组声明。但这不是数组声明。这是引用声明。你为什么一直引用该措辞,即c显然不适用于
const int(&a)[
声明(无论如何解释9.2.3.4的范围)?@geza我恐怕一点也不明白你在说什么。@AnT:如果我们完全忽略9.2.3.4(因为这是一个参考声明),那么是什么指定对象
a
引用的大小为3?@geza:引用初始化规则(在我的问题中链接),假设为了初始化该引用,我们必须生成引用类型的prvalue。该prvalue的类型中不再包含引用。问题基本上归结为,在这种情况下,其类型是否已经“冻结”为不完整的数组类型
const int[]
或者它仍然能够从初始值设定项获取特定大小的
const int[3]
。从字面上看,该措辞似乎表明该类型应该是“冻结的”(即GCC是正确的)。