У меня что-то не так с новым 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
флаг.
Не могли бы вы сказать мне, почему это запрещено? Я должен сказать, что я не понимаю причину.
Большое спасибо (и, пожалуйста, извините, если вопрос глупый …).
Причина в том, что operator[]
определяется следующим образом (обратите внимание, что то же самое справедливо для std::map
):
Value& operator[](Key const& k);
В твоем случае, Key
является A&
, так что это расширяется до:
B& operator[](A& const& k);
А поскольку ссылки на ссылки недействительны и ссылка верхнего уровня отбрасывается при создании с помощью typedefs или параметров шаблона, вы получаете просто:
B& operator[](A&);
Который не может справиться с A const&
аргумент.
В целом, я бы рекомендовал не использовать изменяемую ссылку в качестве ключа, поскольку изменяемые ключи являются хорошим источником ошибок.
Использование ссылки в качестве ключа является плохой идеей: она неизбежно вызывает проблемы, поскольку время жизни карты и ключей не совпадает. Ключевой тип вашей карты ссылок T&
(ну, есть const
добавлено в конце, но это будет незаконно). Пытаясь связать T const&
к T&
не работает Следовательно, вы не можете использовать T const&
искать на карте, используя T&
в качестве ключа.
Есть другие вещи, которые не будут работать. Вы не должны пытаться использовать карту с ключом T&
(или же T*
в этом отношении): используйте значения в качестве ключей!