unordered_map с указанным ключом

У меня что-то не так с новым C ++ unordered_map: я хотел бы использовать operator[] с const ключ, но я получаю отказ.

Я не могу дать весь код, но я могу упростить мою проблему следующим образом:

#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;
}

Вывод компилятора немного длинный, но заканчивается:

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

Я использую const A & потому что в моем коде какой-то метод дает мне его как есть. И, кстати, ключ должен быть постоянным. Я пробовал std::unordered_map<const A &, B> myMap; вместо этого, но это также не работает.

Я использую gcc версии 4.6.3 (Ubuntu / Linaro 4.6.3-1ubuntu5), с -std=c++0x флаг.

Не могли бы вы сказать мне, почему это запрещено? Я должен сказать, что я не понимаю причину.

Большое спасибо (и, пожалуйста, извините, если вопрос глупый …).

3

Решение

Причина в том, что operator[] определяется следующим образом (обратите внимание, что то же самое справедливо для std::map):

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

В твоем случае, Key является A&, так что это расширяется до:

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

А поскольку ссылки на ссылки недействительны и ссылка верхнего уровня отбрасывается при создании с помощью typedefs или параметров шаблона, вы получаете просто:

B& operator[](A&);

Который не может справиться с A const& аргумент.

В целом, я бы рекомендовал не использовать изменяемую ссылку в качестве ключа, поскольку изменяемые ключи являются хорошим источником ошибок.

4

Другие решения

Использование ссылки в качестве ключа является плохой идеей: она неизбежно вызывает проблемы, поскольку время жизни карты и ключей не совпадает. Ключевой тип вашей карты ссылок T& (ну, есть const добавлено в конце, но это будет незаконно). Пытаясь связать T const& к T& не работает Следовательно, вы не можете использовать T const& искать на карте, используя T& в качестве ключа.

Есть другие вещи, которые не будут работать. Вы не должны пытаться использовать карту с ключом T& (или же T* в этом отношении): используйте значения в качестве ключей!

0

По вопросам рекламы [email protected]