Question Details

No question body available.

Tags

c++ vector const-cast

Answers (3)

Accepted Answer Available
Accepted Answer
July 22, 2026 Score: 3 Rep: 123,367 Quality: Expert Completeness: 80%

The objects held by a const std::vector are non-const (assuming T is non-const; I actually can't remember whether T is allowed to be const). This follows from the fact that a constructor can't tell whether it's constructing a const object; since a std::vector initialized to hold some Ts will construct non-const Ts into the buffer it owns, the same constructor call must do exactly the same thing when called for a const vector.

The actual specification is implied by the requirements on T for sequence containers and for std::vector specifically, e.g., for the OP's example of construction from an initializer list, [sequence.reqmts]/8 applies: T must be Cpp17EmplaceConstructible. According to [container.alloc.reqmts]/2.5, this means the expression allocatortraits::construct(m, p, args) is well-formed, where p is of type T*. That means an object of the pointed-to type, T, will be constructed (as implied by the specification of allocatortraits and the Cpp17Allocator requirements).

July 22, 2026 Score: 5 Rep: 21,100 Quality: Medium Completeness: 60%

Consider the initialization of const vector from an input-only range, e.g.:

const std::vector v(std::istreamiterator{std::cin}, {});

Since the size of the range is unknown, the constructor has to allocate with a guessed size and reallocate if the guess is too small. This reallocation needs to move-construct elements in the new storage from rvalues of type T (not const T).

In addition, as an allocator-aware container, vector is required to construct the elements as if by allocatortraits::construct, and destroy the elements as if by allocatortraits::destroy, and neither members of allocatortraits take a pointer to const T.

So at least, during construction and destruction, the elements have to be non-const.

Within the lifetime of the const vector object, the elements may be magically made const. If T is an implicit-lifetime type, a possible mechanism is std::startlifetimeas.

July 22, 2026 Score: 2 Rep: 496,274 Quality: Medium Completeness: 60%

It depends.

Access via a reference or pointer to const

If you start with a non-const vector, but you're accessing the contained object via (for example) a constiterator, any member function of that object you call needs to be marked const. But if it has a mutable member, you can modify that just like you can with any other const object.

You can also use const
cast to bypass all that protection, if you want to badly enough (but you rarely should). For example:

// Warning: this is horrible code written to demonstate a point.
// You don't want to do things like this in real code.

#include #include

class Foo { // fairly normal use of mutable to cache information without // changing logical value of object mutable bool violated = false;

// The value the object stores int i = 0; public:

Foo(int i) : i(i) {}

operator int() const { return i; }

// Normal operator= Foo &operator=(int j) { i = j; return this; }

// horrible violation of expectations and decency Foo const &operator=(int j) const { const_cast(i) = j;

// record the fact that expectations have been violated violated = true; return
this; } };

// accept a reference to const vector, but modify all the elements anyway. // Only works because of the operator= above that accepts a reference to // const, but modifies the value anyway. void do_evil(std::vector const &f) { for (auto const &item : f) item = 0; }

int main() { std::vector f;

for (int i=0; i