const std :: vector< T>的修改元素通过const_cast [英] Modifying element of const std::vector<T> via const_cast
问题描述
以下程序是否具有未定义的行为?
Does the following program have undefined behavior?
#include <iostream>
#include <vector>
struct Foo
{
const std::vector<int> x;
};
int main()
{
std::vector<int> v = {1,2,3};
auto f = new Foo{v};
const_cast<int&>(f->x[1]) = 42; // Legal?
std::cout << f->x[1] << "\n";
}
请注意,它不是使用const_cast
从f->x
中剥离常数,而是从f->x[x]
中剥离常数,这大概是由一个单独的数组表示的.还是允许翻译假定f->x[1]
创建后是不可变的?
Note that it not using const_cast
to strip constness from f->x
, but instead stripping constness from f->x[x]
, which presumably is represented by a separate array. Or is a translation allowed to presume that f->x[1]
is immutable after it is created?
推荐答案
您的示例中没有未定义的行为.
上面的代码不会调用未定义的行为,因为基础数据(int)是可变的.让我们看一个更简单的例子.
There is no Undefined Behavior in your example.
The above code does not invoke undefined behavior because the underlying data (int) is mutable. Let's look at a simpler example.
#include <iostream>
struct IntPtr {
int* data;
};
int main() {
int a = 0;
const IntPtr p { &a };
*p.data = 10;
std::cout << a; // Prints 10
}
所有这一切都是完全合法的,因为将IntPtr
设为const会导致data
是指向int的常量指针,而不是指向常量int的指针.我们可以修改p.data
指向的数据;我们只是不能修改p.data
本身.
All of this is perfectly legal to do because making IntPtr
const results in data
being a constant pointer to an int, NOT a pointer to a constant int. We can modify the data that p.data
points to; we just can't modify p.data
itself.
const IntPtr p { &a };
*p.data = 10; // This is legal
int b;
p.data = &b; // This is illegal (can't modify const member)
那么该示例如何适用于std::vector
?
让我们添加索引到IntPtr
的功能:
So how does this example apply to std::vector
?
Let's add the ability to index into an IntPtr
:
class IntPtr {
int* data;
public:
IntPtr() = default;
IntPtr(int size) : data(new int[size]) {}
// Even though this is a const function we can return a mutable reference
// because the stuff data points to is still mutable.
int& operator[](int index) const {
return data[index];
}
};
int main() {
const IntPtr i(100);
i[1] = 10; // This is fine
};
即使IntPtr
是const,基础数据也是可变的,因为它是通过分配可变int数组创建的. std::vector
相同:基础数据仍然可变,因此const_cast
是安全的.
Even though the IntPtr
is const, the underlying data is mutable because it's created by allocating an array of mutable ints. It's the same for std::vector
: the underlying data is still mutable, so it's safe to const_cast
it.
这篇关于const std :: vector< T>的修改元素通过const_cast的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!