【问题标题】:Syntax for defining const array type用于定义 const 数组类型的语法
【发布时间】:2015-04-06 08:25:55
【问题描述】:

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

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

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

f({1, 2, 3});

原因很简单:非常量 lval 引用不能绑定到 rval 临时。纠正代码的一种方法是:

typedef int ArrOfInt[3];

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

f({1, 2, 3});

我的问题是:C++ 是否有用于 const 数组类型的内联定义的语法,所以首先不需要 typedef

【问题讨论】:

    标签: c++ arrays syntax constants language-lawyer


    【解决方案1】:

    数组没有与其元素分开的 cv 限定,所以你要求的是不存在的东西。符合标准,

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

    ([basic.type.qualifier]/2 in N3936)

    然而,它接着说,当元素类型合格时,数组类型也被认为是合格的:

    ... 一个数组类型,其元素为 cv-qualified 也被认为具有与其元素相同的 cv-qualification。

    ([basic.type.qualifier]/5)

    而且您编写的代码确实可以在没有 typedef 的情况下重写。声明符语法是

    void f(const int (&a)[3]);
    

    const 仍然附加到元素类型,但数组类型也是const,因此引用是对const 类型的左值引用。所以这就是为什么它可以绑定到一个临时的。

    【讨论】:

      【解决方案2】:

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

      似乎没有明确的规范性陈述来回答 数组是否具有 const 限定元素类型的问题 本身是 const 限定的; [...]

      ... 在 C++11 被批准后就解决了。现在 [basic.type.qualifier]/5 内容如下:

      应用于数组类型的 Cv 限定符附加到底层 元素类型,因此符号“cv T”,其中T 是一个数组类型,是指 到其元素如此限定的数组。 一种数组类型,其 元素是 cv-qualified 也被认为具有相同的 cv-qualifications 作为它的元素。

      因此不可能使数组元素const 而不是封闭数组本身,反之亦然。
      例如

      const int arr[2];
      

      这里,arr 是(顶级)conststd::is_const<decltype(arr)>{}true),它的元素也是如此。而在

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

      a 指的是带有const 元素的const 数组。

      【讨论】:

      • 那么当前的 GCC、clang 和 VC 只是不符合标准,因为不编译代码的第一个版本?
      • @Lingxi 第一个版本的代码在任何地方都没有const。如果我将其更改为const int (&a)[3],那么 GCC 会接受。铿锵声也是。
      • @Lingxi 你的代码的第一个版本是不正确的。
      • 啊,是的。我只是忘记了。
      猜你喜欢
      • 2018-10-04
      • 2015-04-02
      • 1970-01-01
      • 1970-01-01
      • 2016-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多