为什么我不能移动地图的元素?
Why Can't I move an Element of a map?
我希望能够更改 map
的元素的键。
我认为一个很好的处理方法是 move
来自 map
的元素,如下所示:
map<char, int> foo{{'a', 1}, {'b', 2}, {'c', 3}};
foo['z'] = move(*foo.find('c')).second;
for(auto& i: foo){
cout << i.first << ' ' << i.second << endl;
}
这输出:
a 1
b 2
c 3
z 3
而不是我希望的:
a 1
b 2
z 3
有什么方法可以实现吗?
I want to be able to change the key of an element of a map.
你不能。 map
的 value_type
是 std::pair<const Key, Value>
。 const
部分很重要。该结构的整个内部布局都基于确保 insert
位于正确的位置。如果您可以更改密钥,则可以使整个结构无效。
您的代码 运行:
foo['z'] = move(*foo.find('c')).second;
只是插入对 ('z', foo['c'])
- move
不做任何事情。请记住:move
只是对右值引用的转换 - 它不会做任何事情,除非它实际上是 move
d,这里什么也没做,也不会有所作为,因为我们正在处理与基本类型。上面这行代码相当于:
foo['z'] = foo.find('c')->second;
这或许可以解释为什么您会看到仅插入一个新的 key/value 对而没有 'c'
被删除的行为。
"change"密钥的正确方法是擦除它然后插入它:
auto it = foo.find('c');
if (it != foo.end()) {
foo.insert(std::make_pair('z', it->second));
foo.erase(it);
}
首先,move
不移动任何东西;它只是将其参数转换为 rvalue,以便其他东西可以从它移动。其次,从一个对象中移出并不会破坏它,或者将它从容器中移除,它只是让它处于有效的、未指定的状态。最后,"moving" 像 pair<const char, int>
这样的简单类型只包含复制它(特别是因为 const
意味着你无论如何都不能修改密钥,如果你强制它会破坏映射变化)。
所以单独移动什么都不做,你的代码等同于
foo['z'] = foo.find('c')->second;
它只是添加了一个新元素和相同映射值的副本。
您可以将映射值移动到新元素,然后删除旧元素。
auto found = foo.find('c');
if (found != foo.end()) {
foo['z'] = move(found->second);
foo.erase(found);
}
我希望能够更改 map
的元素的键。
我认为一个很好的处理方法是 move
来自 map
的元素,如下所示:
map<char, int> foo{{'a', 1}, {'b', 2}, {'c', 3}};
foo['z'] = move(*foo.find('c')).second;
for(auto& i: foo){
cout << i.first << ' ' << i.second << endl;
}
这输出:
a 1
b 2
c 3
z 3
而不是我希望的:
a 1
b 2
z 3
有什么方法可以实现吗?
I want to be able to change the key of an element of a map.
你不能。 map
的 value_type
是 std::pair<const Key, Value>
。 const
部分很重要。该结构的整个内部布局都基于确保 insert
位于正确的位置。如果您可以更改密钥,则可以使整个结构无效。
您的代码 运行:
foo['z'] = move(*foo.find('c')).second;
只是插入对 ('z', foo['c'])
- move
不做任何事情。请记住:move
只是对右值引用的转换 - 它不会做任何事情,除非它实际上是 move
d,这里什么也没做,也不会有所作为,因为我们正在处理与基本类型。上面这行代码相当于:
foo['z'] = foo.find('c')->second;
这或许可以解释为什么您会看到仅插入一个新的 key/value 对而没有 'c'
被删除的行为。
"change"密钥的正确方法是擦除它然后插入它:
auto it = foo.find('c');
if (it != foo.end()) {
foo.insert(std::make_pair('z', it->second));
foo.erase(it);
}
首先,move
不移动任何东西;它只是将其参数转换为 rvalue,以便其他东西可以从它移动。其次,从一个对象中移出并不会破坏它,或者将它从容器中移除,它只是让它处于有效的、未指定的状态。最后,"moving" 像 pair<const char, int>
这样的简单类型只包含复制它(特别是因为 const
意味着你无论如何都不能修改密钥,如果你强制它会破坏映射变化)。
所以单独移动什么都不做,你的代码等同于
foo['z'] = foo.find('c')->second;
它只是添加了一个新元素和相同映射值的副本。
您可以将映射值移动到新元素,然后删除旧元素。
auto found = foo.find('c');
if (found != foo.end()) {
foo['z'] = move(found->second);
foo.erase(found);
}