繁体   English   中英

修改 const std::vector 的元素<T>通过 const_cast

[英]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_castf->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是安全的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM