const std :: vector< T>的修改元素通过const_cast [英] Modifying element of const std::vector<T> via const_cast

查看:210
本文介绍了const std :: vector< T>的修改元素通过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_castf->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&lt; T&gt;的修改元素通过const_cast的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆