修改C ++ unordered_map中复杂类型的值

时间:2016-03-29 20:39:53

标签: c++ c++11

我想了解为什么在我尝试使用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的更改是暂时的。我错过了什么?

4 个答案:

答案 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

您有几种选择:

  1. map[0][1] = 3
  2. vector<int> &foo = map[0]foo[1] = 3之后。
  3. vector<int> *foo = &map[0](*foo)[1] = 3之后。