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...
Could you create a wrapper that contains the value that allows the value to be mutated when const and put that in the map instead? Something like:
template<typename T>
class Mutable {
    mutable T value;
public:
  const Mutable& operator=(const T& v) const { value = v; return *this; }
  T& get() const { return value; }  
};
Then your map can be of type
const std::map<int, Mutable<int>>
Live demo.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With