Reputation: 23
How can I create an unordered_map
, which will work only with the keys I want and throw an error otherwise.
For example, like in python:
my_dict = {
'a': 0,
'b': 0
}
my_dict['c'] # Will raise an error
But in C++, the equivalent code will initialize a 'c': 0
pair.
What to do? The most obvious solution is to check the key before passing it to the map, but for a huge amount of keys it could get bulky with a lot of if
s.
Upvotes: 1
Views: 165
Reputation: 177
Use the type system. Define an enum
with the keys you want, and then only use enum values instead of literals.
enum MyKeys { A, B };
std::unordered_map<MyKeys, int> my_map;
my_map.insert({A,0});
my_map.insert({B,1});
my_map.insert({C,0}); // compile time error
my_map.insert({'C',23}); // compile time error
my_map[A]; // works
my_map[C]; // compile time error
my_map[2]; // compile time error
Upvotes: 0
Reputation: 238311
but in c equivalent code will initialize 'c': 0 pair. What to do?
Simply don't use operator[]
.
You can use the at
member function instead. It behaves similar to pythons dict:
Returns: A reference to the mapped_type corresponding to x in *this
Throws: An exception object of type out_of_range if no such element is present.
Alternatively, you can use find
, which returns an iterator to the element or iterator to end if element doesn't exist instead of throwing an exception.
If you don't want to modify the values, then you can make the map const which will prevent using operator[]
.
If you want to to keep the map modifiable, but not allow adding elements, then you need to define a wrapper class that contains the map in a private member, and delegates the allowed operations.
Upvotes: 4
Reputation: 28872
Use the find
method and not the deference operator to access the unordered map. If an item is not found an end
iterator is returned.
Upvotes: 3