我想了解为什么在我尝试使用operator[]
直接修改值时,在C ++中unordered_map
上使用[]
会给出不同的结果,而不是将值存储在临时对象中。这是一个例子:
unordered_map<int,vector<int>> map;
map.emplace(0, vector<int>(10, 1) );
map[0][0] = 2; // this works
cerr << map[0][0] << endl; // prints out 2 - as expected
auto foo = map[0];
foo[1] = 3; // this does not work -- the value in map[0][1] is still 1
cerr << map[0][1] << endl; // prints out 1, expected: 3
我的理解是map[0]
应该返回对相关值的引用,而不是其副本,但似乎foo
是副本,因为对foo
的更改是暂时的。我错过了什么?
答案 0 :(得分:4)
从map [0]的返回类型构造一个新变量(副本)foo:
auto foo = map[0];
使foo的类型正好是map [0]返回的内容,即使它是一个引用:
decltype(auto) foo = map[0];
引用从map [0]的返回类型中删除任何引用说明符所产生的类型:
auto& foo = map[0];
对从map [0]的返回类型中删除任何引用说明符和const说明符所产生的类型进行const引用:
auto const& foo = map[0];
答案 1 :(得分:0)
map [0]应该返回对相关值的引用
确实如此。
问题实际上就是你写的:
您将值存储在临时对象中,即存储在副本(auto
!)中,而不是引用中。修改副本不会更改原始对象。
答案 2 :(得分:0)
您不希望foo
成为map[0]
的副本,您希望将引用至map[0]
。
所以,将foo
作为参考:
auto& foo = map[0];
^
答案 3 :(得分:0)
=
类型的分配vector<T>
运算符将生成所分配值的副本。这就是auto foo = map[0];
行中发生的事情。 foo
是副本。 Docs
您有几种选择:
map[0][1] = 3
vector<int> &foo = map[0]
和foo[1] = 3
之后。vector<int> *foo = &map[0]
和(*foo)[1] = 3
之后。