Home > Net >  Is it possible to create an STL container where the contents are mutable, but the container's a
Is it possible to create an STL container where the contents are mutable, but the container's a

Time:01-26

This is probably easiest to explain with examples.

std::vector<int> a;
a.push_back(1);
a[0] = 2;
const std::vector<int>& b = a;
b.push_back(1); // Throws an error I want.
b = std::vector<int>(); // Throws an error I want.
b[0] = 2; // Throws an error I don't want.

This is sort of similar to an array declared like: char* const ptr = array; where here the values can be modified, but the pointer to the array can't be changed.

The basic reason for this is to be able to allocate and initialize data in one module, while passing it by reference and having it processed elsewhere. I want to indicate that the underlying allocations shouldn't be manipulated.

This could sort of be achieved for the containers with a data() function by just passing this data pointer instead of the container. Also, if I were to write my own class, I suppose I could achieve something like this with mutable or const_casts, but I was curious if there's any STL feature I was missing.

CodePudding user response:

No, none of the standard library containers offer that behavior. You will need to write your own container or adapt one from the standard library ones to have this feature.

However, if you do not want to allow modifying the containers themselves (only their elements), then consider passing the range of the elements contained in the container instead the container itself to your users.

For example (pre-C 20) pass a.begin() and a.end() as an iterator pair denoting the range of elements to the user. The user doesn't need to care about where the iterators originate from if they only need to access the elements in the range and they can't modify the container itself through the iterators.

Since C 20 pass the range of elements as some form of view range. For example for contiguous containers, such as std::vector, pass as a std::span constructed from the container. std::span basically encapsulates passing .data() and .size() of such containers, as you also suggested.

  • Related