對於容器類(如std::vector
),存在兩個不同的恆定性概念:容器的大小(即大小)和元素的大小。看來,std::vector
混淆這兩個,使得下面簡單的代碼不會編譯:const與容器的非常量及其內容
struct A {
A(size_t n) : X(n) {}
int&x(int i) const { return X[i]; } // error: X[i] is non-const.
private:
std::vector<int> X;
};
注意的是,即使數據成員(中三分,將開始數據和結束的&結束的分配緩衝區)的std::vector
是不是通過調用它的operator[]
改變,這個成員不是const
- 這不是一個奇怪的設計?
還要注意,對於原始指針,恆定的煩躁這兩個概念都整齊分離,使得所述相應的原始指針代碼
struct B {
B(size_t n) : X(new int[n]) {}
~B() { delete[] X; }
void resize(size_t n); // non-const
int&x(int i) const { return X[i]; } // fine
private:
int*X;
};
作品就好了。
那麼當使用std::vector
(不使用mutable
)時,正確/推薦的方法是什麼?
是一個const_cast<>
如
int&A::x(int i) const { return const_cast<std::vector<int>&>(X)[i]; }
認爲是可接受的(X
已知是非const
,所以沒有UB這裏)?
EDIT只是以防止進一步的混亂:我想修改的元件,即所述容器的內容而非容器本身(大小和/或存儲器位置)。
'std :: vector'的數據可以通過調用'operator []'來改變。正如你寫的A :: X,a.x(1)++;是完全合法的,並且修改了向量的內容。 – 2013-02-11 16:14:10
@DavidSchwartz矢量的*內容*不是它的實際*數據*(儘管你可能在邏輯上將它們關聯起來)。如果你檢查'std :: vector',它只有3個指針作爲數據(數據的開始和結束以及緩衝區的結束)。這些保持不變。 – Walter 2013-02-12 19:52:10