const向量意味着const元素?

cib*_*en1 32 c++ const

是否const vector<A>意味着它的元素也是const如此?

在下面的代码中,

v[0].set (1234); in void g ( const vector<A> & v ) 产生编译器错误

const.cpp:28:3:错误:成员函数'set'不可行:'this'参数的类型为'const value_type'(又名'const A'),但函数未标记为const

为什么?

(*v[0]).set(1234);void h ( const vector<A *> & v ) 是编译器确定.

版本之间有什么区别?

// ...........................................................
class A {
private:
  int a;
public:
  A (int a_) : a (a_) { }
  int get () const { return a; }
  void set (int a_) { a = a_; }
};

// ...........................................................
void g ( const vector<A> & v ) {
  cout << v[0].get();
  v[0].set (1234); 
} // ()

// ...........................................................
void h ( const vector<A *> & v ) {
  cout << (*v[0]).get();
  (*v[0]).set(1234);
} // ()
Run Code Online (Sandbox Code Playgroud)

lis*_*rus 24

是的,a const vector提供对其元素的访问,就像它们一样const,也就是说,它只提供const引用.在你的第二个功能,它不是类型的对象Aconst,但三分球给他们.指针const并不意味着指针指向的对象是const.要声明指向const的指针,请使用该类型A const *.

  • 不,元素不是`const`,那就是`vector <const A>`.您无法获得非const引用或指向它们的指针. (7认同)
  • @MikeSeymour 作为旁注:“向量&lt;const T&gt;”是不可能的。`T` 不允许是 `const` 或 `volatile`。另请参阅此处的答案:/sf/answers/486873271/ (3认同)
  • @ cibercitizen1否。在第二个功能“ h”中,您没有更改指针,但是指针指向了“ A”。指针指向非const A,所以这不是问题。容器仅使您可以通过const访问保存在其中的指针,因此您无法更改其指向的对象。 (2认同)

das*_*ght 14

第一个版本

v[0].set (1234); 
Run Code Online (Sandbox Code Playgroud)

不编译,因为它试图通过引用更改向量返回的向量的第一个元素.编译器认为这是一个更改,因为set(int)没有标记const.

另一方面,第二个版本仅从向量中读取

(*v[0]).set(1234);
Run Code Online (Sandbox Code Playgroud)

并调用set取消引用它返回的指针的常量引用的结果.

当你调用v[0]一个const向量时,你会得到一个const引用A.当元素类型是指针时,调用set它就可以了.您可以将第二个示例更改为

v[0]->set(1234);
Run Code Online (Sandbox Code Playgroud)

并得到与以前相同的结果.这是因为您获得了一个常量指针的引用,但该指针指向的项不是常量.

  • 我最喜欢这个答案.在其他世界中,就像说const vector <T>同时生成向量和T const,无论TIe如何,在const向量中<A>对象A应该被视为const.在const向量<A*>中,A*应该是const,但不是它们指向的. (3认同)

Bil*_*nch 9

所以const对象只能调用const方法.那是:

class V {
  public:
    void foo() { ... }        // Can't be called
    void bar() const  { ... } // Can be called
};
Run Code Online (Sandbox Code Playgroud)

那么让我们看一下vector的operator []:

reference       operator[]( size_type pos );
const_reference operator[]( size_type pos ) const;
Run Code Online (Sandbox Code Playgroud)

所以当vector对象是const时,它将返回一个const_reference.

关于: (*v[0]).set(1234);

让我们打破这个:

A * const & ptr = v[0];
A & val = *ptr;
val.set(1234);
Run Code Online (Sandbox Code Playgroud)

请注意,您有一个指向变量数据的常量指针.因此,您无法更改指向的内容,但您可以更改指针指向的值.


ein*_*ica 9

是的,因为std::vector值类型而不是引用类型。

更简单地说:Anstd::vector将其缓冲区中的值视为自身的一部分,因此更改它们意味着更改向量。如果我们只将向量视为保存指向已分配缓冲区的指针和大小,这可能会令人困惑:当我们更改缓冲区中的元素时,我们不会更改这两个字段。

它与指针相反,指针是引用类型;如果你改变了指向的值,你并没有改变指针本身。

std::vector值类型这一事实是一种设计选择——它不是 C++ 语言固有的东西。因此,例如,std::span类基本上也是一对指针和大小,但std::span可以是const,但您仍然可以更改指向的元素。(跨度和向量之间还存在其他差异。)