【问题标题】:const propagation to std::array of pointersconst 传播到 std::array 指针
【发布时间】:2017-01-12 23:47:15
【问题描述】:

为什么std::array的数据类型在这里被不同的实例化

using T = const int *;
std::array<T, 4> x = { &a, &b, &c, &d }; // name: class std::array<int const *,4>
x[0] = &c; // OK    : non-constant pointer
*x[0] = c; // Error : constant data

和这里相比?

using T = int *;
std::array<const T, 4> x = { &a, &b, &c, &d }; // name: class std::array<int * const,4>
x[0] = &c; // Error : constant pointer
*x[0] = c; // OK    : non-constant data

第二种情况等价于const std::array&lt;T, 4&gt;(指向非常量数据的常量指针)。 如果我们直接使用const int *std::array&lt;const int*, 4&gt;,我们会得到第一种情况的行为。

那么更准确地说,为什么using T = int*; std::array&lt;const T, 4&gt;; 等同于std::array&lt;int*const, 4&gt; 而不是std::array&lt;const int*, 4&gt;

【问题讨论】:

  • 简短的回答是:因为这就是 C++ 的工作方式。类型是指向某物的指针。应用 const 修饰符使其成为指向某物的常量指针。结束。
  • 我想在胸前纹上你的家庭住址,不代表你不能搬家。
  • 一个是指向可变对象的 const 指针,一个是指向 const 对象的可变指针
  • 谢谢大家!我缺少的一点是const T 限定T 为常数,在T 被推导/替换之前。我错误地认为T 被直接替换(像宏一样),而不是被视为自己的类型,有自己的限定符。
  • 这就是为什么我更喜欢将const 放在它限定的类型之后。这样T constT = int * 就应该变成int * const

标签: c++ arrays pointers constants type-deduction


【解决方案1】:

为什么using T = int*; std::array&lt;const T, 4&gt;; 等同于std::array&lt;int*const, 4&gt; 而不是std::array&lt;const int*, 4&gt;

因为constT 上是合格的,指针本身,它不是(也不可能)在指针上合格。所以const T 表示const 指针,而不是指向const 的指针。

规则是一样的,T是不是指针。

using T = int;   // const T => int const
using T = int*;  // const T => int* const, not int const*
using T = int**; // const T => int** const, neither int* const*, nor int const**

注意第三个例子,如果const在pointee上合格,const T应该是int* const*,或者它应该在pointee的pointee上合格,即int const**

【讨论】:

  • 感谢您的回答!只是为了确保我已经理解,我的想法是否正确:类型推导发生在 const 限定之后?还是比这更复杂?
  • @Judge 这里没有类型推导,类型是明确指定的。
  • 好点 :) 并感谢您的编辑,现在这样在字典上更有意义。让我重新表述这个问题: const 限定是否发生在类型替换之前?其他修饰符也是如此,例如volatile
  • @Judge 如果我正确理解您的问题,是的,首先出现 const 限定,然后确定类型。是的,volatile 也是如此。
  • 这为我解决了很多困惑,谢谢!
【解决方案2】:
using T = const int *; //T is a pointer to a CONSTANT integer.
std::array<T, 4> x = { &a, &b, &c, &d }; //array of PointerToConstantInteger, size=4

更改数组x 的元素,但不要取消引用并尝试更改其中存储的值。

using T = int *;  //T is a pointer to an integer.
std::array<const T, 4> x = { &a, &b, &c, &d }; //array of CONSTANT IntegerPointer, size=4

无法更改数组x 的元素,但取消引用和更改其中存储的值没有问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-09
    相关资源
    最近更新 更多