带有引用键的unordered_map

3

我在使用新的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 &,因为在我的代码中,一些方法将它原样给予我。而且,顺便说一下,关键字应该是const。我尝试了std::unordered_map<const A &, B> myMap;,但也不起作用。
我使用的是gcc版本4.6.3(Ubuntu/Linaro 4.6.3-1ubuntu5),并带有-std=c++0x标志。
请问为什么这是被禁止的?我必须说我不理解原因。
非常感谢(如果问题很蠢,请原谅...)。

我不能提供整个代码,但我可以像这样简化我的问题 +1,因为这正是我们希望你在提问时做的事情,尝试将其缩小到最小可能存在问题的示例。 - Benjamin Lindley
再次感谢整个社区。我很快得到了许多准确和有用的答案。太棒了! - unamourdeswann
2个回答

4
原因在于operator[]被规定如下(注意同样适用于std::map):
Value& operator[](Key const& k);

在您的情况下,KeyA&,因此展开为:
B& operator[](A& const& k);

由于引用到引用是无效的,并且通过typedef或模板参数创建时会删除顶级引用,因此您只会得到:

B& operator[](A&);

无法处理 A const& 参数。

一般来说,我建议不要使用可变引用作为键,因为可变键是错误的一个好源头。


是这样吗?非常感谢您的回答。我不知道这个。这些技术细节对我来说仍然是一个谜。 - unamourdeswann

0

使用引用作为键是一个坏主意:这必然会导致问题,因为映射和键的生命周期不一致。你的引用映射的键类型是T&(末尾加上const是非法的)。试图将T const&绑定到T&是行不通的。因此,你不能使用T const&来查找使用T&作为键的映射。

还有其他一些事情是行不通的。你不应该尝试使用键为T&(或者T*)的映射:使用值作为键!


不是 map 是 const,而是 key 是。 - Xeo
@Xeo:没错。你也不能将T const&绑定到一个T&,这是尝试在此处使用的关键类型(即使假设映射中的其他所有内容都使用引用,实际上并非如此)。 - Dietmar Kühl
非常感谢。我现在明白为什么这个映射实际上是一个概念上的缺陷了。我会立即进行更改。 - unamourdeswann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接