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

时间:2019-04-05 22:26:33

标签: c++ arrays reference list-initialization

以下代码在Clang中可以正常编译,并输出mosaicplot数组的大小

int [3]

但是,在GCC中,该声明可以很好地编译,但是#include <iostream> int main() { const int (&a)[] = { 1, 2, 3 }; std::cout << sizeof a << std::endl; } 不能编译:显然,GCC拒绝“推导”数组大小,并以sizeof a作为对a的引用类型,不完整。

这种初始化的预期行为是什么?

9.3.4/3似乎是此类情况下标准的相关部分,但就其本身而言,似乎并不能得出结论。

1 个答案:

答案 0 :(得分:1)

关于这一点,标准尚不完全清楚,我认为GCC的解释很可能就是WG21的意图,但我不确定。

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

  

当声明符后跟 initializer (11.6)或静态数据成员的声明符后跟 brace-or-equal-时,也可以省略数组绑定初始化程序(12.2)。在这两种情况下,边界都是根据提供的初始元素(例如N)的数量(11.6.1)来计算的,D标识符的类型是“ N的数组T”。

这并不完全是仅适用于数组本身的声明,还是在引用数组时也应适用,因为在解释[dcl.ref]时必须递归地咨询[dcl.array] ](描述&&&运算符)。但是,我认为应该拒绝后者的解释,因为当[]被深深地埋在声明器中时,我们不会期望初始化器会导致推导边界。明智地考虑一下人为的例子:

int (*a[1])(const int (&)[]) = {0};

这里是GCC和Clang agree,我认为常识也同意,a的类型是int (*[1])(const int (&)[]),而不是int (*[1])(const int (&)[1]):{{ 1}}具有一个初始化程序,不会导致内部数组的绑定被推导。

基于此,我认为GCC在不推导代码中绑定的数组方面是正确的,因此a的类型为a