通过 const_cast 修改 const std::vector<T> 的元素
Modifying element of const std::vector<T> via const_cast
以下程序是否有未定义的行为?
#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]
在创建后是不可变的?
您的示例中没有未定义的行为。
以上代码不会调用未定义的行为,因为底层数据 (int) 是可变的。让我们看一个更简单的例子。
#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
本身。
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
:
的能力
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
是常量,底层数据也是可变的,因为它是通过分配可变整数数组创建的。 std::vector
也是一样:底层数据仍然是可变的,所以 const_cast
它是安全的。
以下程序是否有未定义的行为?
#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]
在创建后是不可变的?
您的示例中没有未定义的行为。
以上代码不会调用未定义的行为,因为底层数据 (int) 是可变的。让我们看一个更简单的例子。
#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
本身。
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
:
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
是常量,底层数据也是可变的,因为它是通过分配可变整数数组创建的。 std::vector
也是一样:底层数据仍然是可变的,所以 const_cast
它是安全的。