std::unordered_map::operator[]-为什么有两个签名
std::unordered_map::operator[] - why there are two signatures?
在C++11中,有两个版本的std::unordered_map::operator[],即:
mapped_type& operator[] ( const key_type& k ); //1
mapped_type& operator[] ( key_type&& k ); //2
有两个问题:
1( 为什么需要第二个-第一个允许将常量传递给函数,因为第一个包含关键字const
2( 例如,在这种情况下,将调用哪个版本,1或2:
std::unordered_map<std::string, int> testmap;
testmap["test"] = 1;
通常,键只用于比较目的,所以您可能想知道为什么rvalue语义是必要的:const引用应该已经涵盖了这种情况。
但需要注意的是,运算符[]确实可以创建一个新的键/值对:如果映射中还不存在键。
在这种情况下,如果使用了第二个重载,则映射可以安全地移动映射中提供的键值(同时默认初始化该值(。在我看来,这是一个非常罕见且可以忽略不计的优化,但当你是C++标准库时,你不应该不遗余力地为某人节省一个周期,即使它只发生过一次!
至于第二个问题,我可能错了,但它应该认为第二个过载是最好的过载。
编辑:还有一个有效的观点是,它可能允许您使用仅移动对象作为键值,即使这是一个有争议的决定
它是出于性能原因而存在的。例如,如果关键点是右值,则插入新元素时会移动关键点而不是复制关键点。
因此,可以避免对象/键的额外副本。您可以在以下示例中看到这一点:
#include <iostream>
#include <unordered_map>
struct Foo {
Foo() { std::cout << "Foo() called" << std::endl; }
Foo(Foo const &other) { std::cout << "Foo(Foo const &other) called" << std::endl; }
Foo(Foo &&other) { std::cout << "Foo(Foo &&other) called" << std::endl; }
int i = 0;
};
bool operator==(Foo const &lhs, Foo const &rhs) {
return lhs.i == rhs.i;
}
void hash_combine(std::size_t& seed, const Foo& v) {
std::hash<int> hasher;
seed ^= hasher(v.i) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
struct CustomHash {
std::size_t operator()(Foo const& v) const {
std::size_t res = 0;
hash_combine(res, v);
return res;
}
};
int main() {
std::unordered_map<Foo, int, CustomHash> fmap;
Foo a;
a.i = 100;
fmap[a] = 100;
fmap[Foo()] = 1;
}
现场演示
输出:
Foo() called
Foo(Foo const &other) called
Foo() called
Foo(Foo &&other) called
正如在fmap[Foo()] = 1;
中可以看到的那样,与调用复制构造函数的语句fmap[a] = 100;
相比,右值对象被移动。
相关文章:
- 如何在C++中从两个单独的for循环中添加两个数组
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 如何返回一个类的两个对象相加的结果
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 两个字符串在 c++ 中不相等
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 两个文件使用彼此的功能-如何解决
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身
- 如何获取两个 std::map 的公钥?
- 当两个 std::map 对象相同时
- 如何实现 std::map::查找包含两个结构'Pos'结构的比较逻辑,每个结构包含 x 和 y 坐标
- 在c++中将两个相关的std::堆栈合并为std::map的计算效率如何?
- c++中查找两个std::map之间匹配的有效方法
- 在C++中,如何让两个类通过向量(map,multimap.)相互链接
- 两个 std::map 的值是彼此的迭代器?
- 比较两个map::迭代器:为什么需要std::pair的复制构造函数