c++pointersiterationconstantscontainer-data-type

range based for loop with const shared_ptr<>


I have a container with shared_ptr<>, e.g. a vector<shared_ptr<string>> v and I'd like to iterate over v indicating const-ness.

This code:

vector<shared_ptr<string>> v;
v.push_back(make_shared<std::string>("hallo"));
...

for (const auto &s : v) {
    *s += ".";   // <<== should be invalid
}

looks like what I want to do (indicating that s is const) but of course it does not make the string const.

Is there an elegant way to iterate over a container of shared_ptr which makes clear that the content won't be modified?

Something like

for (shared_ptr<const string> s : v) {
    *s += ".";   // <<== will not compile
}

(but this code would not compile for other reasons :))

Edit:

I made a mistake. Originally I was declaring a reference, which results in a compiler error

for (shared_ptr<const string> &s : v) {   // <<== does not compile
    ...
}

If you declare a shared_ptr<const string> the example works. In my eyes this is a good trade-off but this way the pointer gets copied which can be time consuming in loops with little code and big containers..


Solution

  • This is a well-known limitation of C++ that some don't consider to be a limitation.

    You want to iterate constly, but an immutable pointer doesn't imply an immutable pointee.

    The type shared_ptr<string> and the type shared_ptr<const string> are effectively unrelated.

    Option 1

    for (const auto& ptr : v) {
        const auto& s = *ptr;
    
        s += ".";   // <<== is invalid
    }
    

    Option 2

    Just don't modify it.