C++ STL无序映射(unordered_map)的问题和疑惑

4

经过一些年的Java和C#编程,现在我又回到了C++。当然,我的编程风格受到这些语言的影响,我倾向于使用一个我经常使用的特殊组件:哈希映射(HASH MAP)。在STL中,有hash_map,但GCC表示它已被弃用,并且我应该使用unordered_map。因此,我转向了unordered_map。我承认,我不确定我所做的东西的可移植性,因为我必须使用编译器开关-std=c++0x来启用这个特性,这是即将发布的标准之一。无论如何,我对此感到满意,只要能使它工作,因为如果我把它放在我的类中

std::unordered_map<unsigned int, baseController*> actionControllers;

并且使用方法:

void baseController::attachActionController(unsigned int *actionArr, int len,
        baseController *controller) {
    for (int i = 0; i < len; i++){
        actionControllers.insert(actionArr[i], controller);
    }
}

出现了通常的象形文字,表示找不到插入物...有什么提示吗?


顺便问一下,为什么不使用std::map呢?那样可以解决你的可移植性问题。 - hrnt
1
一个映射表并不具有哈希表相同的访问时间保证...这就是为什么我使用它的原因。 - gotch4
5个回答

18

insert 接受一个单一的参数,这个参数是一个键值对,类型为 std::pair<const key_type, mapped_type>。所以你可以像这样使用它:

actionControllers.insert(std::make_pair(actionArr[i], controller));

这是一个例子,如果标准提供了一个重载来完成这个操作就会很好。 - deft_code
@deft_code:像……unordered_map::emplace?http://www.cplusplus.com/reference/unordered_map/unordered_map/emplace/ "两个参数:一个用于键,另一个用于映射值。" - Mooing Duck

9

只需使用:

actionControllers[ actionArr[i] ] = controller;

这是Java一直欠你的操作符重载 :)


5
+1:好观点。值得注意的是insertmap[key] = value;之间的区别:如果map已经有一个键的条目,则map[key] = value;将更改现有的值,而map.insert(make_pair(key,value))则不会(并且有一个返回值表示它失败了)。 - Mike Seymour
1
此外,map[key] = v 首先在 map 中创建一个条目,该条目的默认值为 v 的类型,然后才将值 v 复制到该条目中。对于复杂类型,性能可能会有所差异。 - Xavier Nodet

4

如果您已决定使用(实验性且尚未准备好的)C++0x,则可以使用以下语法将键值对插入到unordered_map中:

  actionControllers.insert({ actionArr[i], controller });

这是由gcc 4.4.0支持的。


2

尝试:

actionControllers.insert(std::make_pair(actionArr[i], controller));

1

STL中的insert通常是map.insert(PAIR(key, value));。也许这就是你的问题所在?

PAIR应该是std::unordered_map<unsigned int, baseController*>::value_type


3
哇,伙计,std::make_pair 是你的好朋友。 - deft_code
它们是同样的东西,所以只是取决于个人喜好。有些人喜欢使用std::make_pair,而其他人则喜欢使用typedef,这样你就可以看到你正在插入什么。除了make_pair可能会使用额外的函数调用之外,两者之间没有其他区别。 - laura
1
@laura:如果类型不完全匹配,则typedef和make_pair之间存在差异。 - Mooing Duck

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