定义常量数组类型的语法

4

请注意,我只对C++语法的可能性感兴趣,而不是任何实际应用。

定义数组类型很容易。例如,int a[3];定义了一个由3个int元素组成的数组类型,而const int a[3];int const a[3];则定义了一个由3个const int元素组成的数组类型。这三种形式都没有定义某种类型Tconst数组(当然,这种类型本身可以被const修改)。因此,下面的代码将无法编译:

void f(int (&a)[3]) {...}

f({1, 2, 3});

原因很简单:非const左值引用无法绑定到右值临时对象。修正代码的一种方法是:
typedef int ArrOfInt[3];

void f(const ArrOfInt& a) {...}

f({1, 2, 3});

我的问题是:C++是否有内联定义const数组类型的语法,以便首先不需要typedef?
2个回答

5

数组没有与其元素分离的cv限定符,因此您要求的内容是不存在的。引用标准:

应用于数组类型的任何cv限定符都会影响数组元素类型,而不是数组类型(8.3.4)。

(N3936中的[basic.type.qualifier]/2)

但是,它继续说,当元素类型受到限定时,数组类型也被认为是受到限定的:

…其元素带有cv限定符的数组类型也被认为具有相同的cv限定符。

([basic.type.qualifier]/5)

您编写的代码确实可以在不使用typedef的情况下重写。声明符语法为

void f(const int (&a)[3]);
< p > const 仍然附加到元素类型,但数组类型也是 const,因此引用是对 const 类型的左值引用。这就是为什么它可以绑定到临时对象的原因。


1

这是核心问题#1059的主题:

似乎没有一个明确的规范声明回答以下问题:具有const限定符元素类型的数组是否本身具有const限定符;[...]

...在 C++11 正式发布后不久得到解决。现在,[basic.type.qualifier]/5 读取如下:

应用于数组类型的Cv限定符附加到底层元素类型,因此符号“cvT”,其中 T 是数组类型,指的是其元素具有相同的限定符的数组。具有cv限定符元素的数组类型也被认为具有与其元素相同的cv限定符。

因此,无法使数组元素保持const而不使封闭数组本身成为常量,反之亦然。例如:

const int arr[2];

在这里,arr 是(顶层)const 的(std::is_const<decltype(arr)>{}true),其元素也是如此。并且在…
void f(const (&a)[3]) {...}

a 指代一个具有 const 元素的 const 数组。


那么当前的GCC、clang和VC都不符合标准,不能编译代码的第一个版本? - Lingxi
1
@Lingxi,代码的第一个版本没有任何const。如果我将其更改为const int (&a)[3],那么GCC会接受它。clang也是如此。 - user743382
@Lingxi,你的代码第一个版本是错误的。 - Columbo
啊,是的。我刚忘了那个。 - Lingxi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接