const reference of map - operator[]

This code gives me a huge template-mess error:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct Node {
    std::unordered_map <std::size_t, std::size_t> map;
};

void test(const Node& node)
{
    std::size_t curr_node = 33;
    const std::size_t i = node.map[curr_node];
    
    std::cout << i << std::endl;
}

int main()
{
    Node node;
    node.map[1]  = 0;
    node.map[33] = 1;
    test(node);
}


Here's the error:
13 45 [Error] passing 'const std::unordered_map<long long unsigned int, long long unsigned int>' as 'this' argument of 'std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type& std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::operator[](const _Key&) [with _Key = long long unsigned int; _Pair = std::pair<const long long unsigned int, long long unsigned int>; _Hashtable = std::_Hashtable<long long unsigned int, std::pair<const long long unsigned int, long long unsigned int>, std::allocator<std::pair<const long long unsigned int, long long unsigned int> >, std::_Select1st<std::pair<const long long unsigned int, long long unsigned int> >, std::equal_to<long long unsigned int>, std::hash<long long unsigned int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>; std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type = long long unsigned int]' discards qualifiers [-fpermissive]

From previous experience, I remembered that the "discards qualifiers" means the compiler doesn't like that it's a const reference or object calling a non-const function (in this case the operator[] ).

As predicted, if I make the test function be defined as
1
2
void test(Node& node) {
    ...

then it compiles and works fine.

So here's the issue:
I like the pleasant syntax of being able to use the [] operator.
Am I forced to use map.find() instead in this situation? There shouldn't be any performance difference, right?
Last edited on
> Am I forced to use map.find() instead in this situation?

Yes. operator[]() performs an insertion intoi the map if the key does not exist; so it is not available on const maps.

> There shouldn't be any performance difference, right?

Right. Do the look up only once:
1
2
3
4
5
6
7
void test(const Node& node)
{
    std::size_t curr_node = 33;
    const auto iter = node.map.find(curr_node);
    
    if( iter != node.map.end() ) std::cout << iter->second << '\n';
}
Last edited on
Thanks for the fast response =)
@below Thanks norm b too, although I'll probably just go with the find.
Last edited on
Topic archived. No new replies allowed.