c++dictionaryconstants

map with const keys but non const values?


I have a situation, where I would like to have a map that does not allow to add/remove keys after initialization, but the values are allowed to change (thus I cannot simply make the map const). Ie

/*semi-const*/ map<int,int> myMap = initMap();

myMap[1] = 2;                  // NOT OK, because potentially adds a new key
myMap.at(1) = 2;               // OK, because works only if key is present
for (auto & element : myMap) {
    element.second = 0;        // OK, values may change
}

I could write my own wrapper for std::map, but I have the feeling that it is something not too uncommon, so I wonder if there is already an existing solution.

Is there some standard idiom for a map that does not allow adding/removing keys, while the values may change?

ps: I know that the title alone is a bit vague, because the keys are already const in a map, but I hope it is clear what I mean...


Solution

  • I usually regard this as a pitfall in C++ more than a feature, but, if it fits your application, you can just use pointer values.

    #include <map>
    #include <memory>
    
    int main(int argc, char ** argv)
    {
        using namespace std;
        const map<int, shared_ptr<int>> myMap = { {1, make_shared<int>(100)} };
        // *(myMap[1]) = 2;  // Does not compile
        *(myMap.at(1)) = 2;
        for (auto & element : myMap)
        {
            *(element.second) = 0;
        }
        return 0;
    }
    

    Which is really just a simpler version of this other answer (obviously you may choose between shared_ptr / unique_ptr as needed).