Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unordered_map with referenced key

I have something wrong with the new C++ unordered_map: I would like to use the operator[] with a const key, but I get rejected.

I cannot give the whole code, but I can simplify my problem like this:

#include <unordered_map>

class A {
    public:
        A();
};

class B {
    public:
        B();
};

int main(int argc, char **argv) {
    std::unordered_map<A &, B> myMap;
    A a;
    const A &ar = a;
    B b;
    myMap[ar] = b;
}

The output of the compiler is a bit long, but ends with:

/usr/include/c++/4.6/bits/hashtable_policy.h:537:5: note:   no known conversion for argument 1 from ‘const A’ to ‘A&’

I use a const A & because, in my code, some method give it to me as is. And, by the way, the key should be const. I have tried a std::unordered_map<const A &, B> myMap; instead, but it does not work either.

I use gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5), with the -std=c++0x flag.

Could you please tell me why this is forbidden? I must say I do not understand the reason.

Many thanks (and please excuse me if the question is stupid...).

like image 444
unamourdeswann Avatar asked May 20 '26 20:05

unamourdeswann


1 Answers

The reason is that operator[] is specified as follows (note that the same holds for just std::map):

Value& operator[](Key const& k);

In your case, Key is A&, so this expands to:

B& operator[](A& const& k);

And since references-to-references are invalid and the top-level reference is dropped when created through typedefs or template parameters, you get just:

B& operator[](A&);

Which can't handle an A const& argument.

In general, I'd advise against using a mutable reference as the key, since mutable keys are a good source for errors.

like image 166
Xeo Avatar answered May 23 '26 10:05

Xeo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!