Modifying element of const std::vector via const_cast

前端 未结 1 1637
-上瘾入骨i
-上瘾入骨i 2021-02-07 18:39

Does the following program have undefined behavior?

#include 
#include 

struct Foo
{
    const std::vector x;
};

int m         


        
1条回答
  •  无人及你
    2021-02-07 19:28

    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 
    
    struct IntPtr {
        int* data;
    };
    
    int main() {
        int a = 0;
        const IntPtr p { &a }; 
        *p.data = 10;
        std::cout << a; // Prints 10
    }
    

    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)
    

    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
    };
    

    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.

    0 讨论(0)
提交回复
热议问题