为什么 int 指针的 const 向量中的取消引用元素是可变的?

Why is dereferenced element in const vector of int pointers mutable?

我不确定 const vector<int *> 的真正含义,所以我编译了下面的代码来了解一下,但现在更加困惑了。

vector<int *> v;
int x = 1, y = 2;
v.push_back(&x);
v.push_back(&y);

const vector<int *> w = v;
w[0] = &y;   //failed. Element is a constant pointer?
*(w[0]) ++;  //failed. Element pointer references to constant value?

如果我在这里停下来,我会假设 const vector<int *>const int * const 的向量,但后来我尝试了以下显然与该假设相矛盾的内容。

*(w[0]) += 3; //passed. Value not constant?
*(w[0]) = 20; //passed. Why...

现在 *(w[0]) 出于我不知道的原因,显然对待 +++= 以及分配不同。我说服自己 const vector 只声明了 vector class 的常量对象,上面的结果可能取决于 vector [=29] 的运算符重载的实际实现=].但我无法解决这个问题。请问有谁能帮忙解释一下吗?

如果相关,我在 Mac.

上使用了 g++ 4.2

这是operator precedence的事情。

当您执行 *(w[0]) ++ 时,您试图修改 指针

当您执行*(w[0]) += 3时,您修改了指针指向的数据。

Why is dereferenced element in const vector of int pointers mutable?

对于const vector<int *>,元素将是const指向非const的指针,即int * const,所以你可以修改指针指向的对象,但是不是指针本身。

根据Operator Precedence,后缀自增运算符的优先级高于operator*,所以*(w[0]) ++;等价于

* ((w[0]) ++);

首先对指针进行自增,然后失败。 w[0] = &y; 也在尝试修改指针,所以也失败了。

另一方面,(*w[0]) ++;(即在指针上增加)会很好。下面的语句也很好,因为它们都修改了指针指向的对象,而不是指针。

*(w[0]) += 3; //passed.
*(w[0]) = 20; //passed.

w 是一个 const vector<int *>const 限定符 应用于向量。因此,相应的const成员函数将用于operator[]

const_reference operator[]( size_type pos ) const;

因为向量是 const 限定的并且包含 int * 类型的元素(而不是 const int *),所以表达式 w[0] 的类型是 int * const&(而不是 const int *&)。也就是说,它是对指向 int 的常量指针的 引用,而不是对指向常量 int[= 的指针的 引用43=]:constness 应用于指针本身,而不是指向的数据。

通过执行 *(w[0]) += 3,您不会修改向量 returns(即 const)指针的 值,但是 这个指针指向的值。因为这个指针是 int * const 类型(而不是 const int *),你可以修改它指向的内容,所以它确实有效。但是,w[0] = &y 是对常量指针进行赋值,因此无法编译。

const vector<T> 允许您以 T const & 的形式访问其元素( const T &)。在这种情况下,Tint *,所以这是 int * const &,一个指向 int 的指针的 const 引用。指针是常量,但int不是。

向量的类型需要是vector<int const *>vector<const int*>),在这种情况下,可以通过[=19访问元素=].

最重要的是,constness 对模板具有传递性,但对指针不具有传递性。如果您将指针放在模板中,您会同时获得这两种行为。