c++ - 将其 move 到 map 后访问一对

标签 c++ c++11 map move-semantics std-pair

如果我将一对 move 到映射中,但由于键已经存在而导致插入失败,我可以在之后安全地使用该对吗?

//objects available: map, pair

auto insert_pair = map.insert(std::move(pair));

if (!insert_pair.second)
{
  //can I safely access pair here?
}

这是否记录在标准中?

最佳答案

鉴于规范的当前状态,您不能对函数调用返回后参数的状态做出任何假设,这看起来多么荒谬(请阅读下文)。

要了解原因,我们首先要指出 insert()成员函数是根据 emplace() 定义的(见 23.4.4.4/1):

The first form is equivalent to return emplace(std::forward<P>(x)). [...]

emplace()的后置条件依次指定为(参见第 23.2.4 节,表 102):

Inserts a value_type object t constructed with std::forward<Args>(args)... if and only if there is no element in the container with key equivalent to the key of t. The bool component of the returned pair is true if and only if the insertion takes place, and the iterator component of the pair points to the element with key equivalent to the key of t.

上面引用的粗体句子(强调是我的)说如果键不存在,将成为映射元素的对将直接从您提供的右值对。

这将使非常非常合理推断实现将首先必须检查 key 是否存在,只有在不存在的情况下,才从您的对中 move 构建新 map 的元素。

但是,在处理形式语言的规范时,“非常非常合理”并不是一个有效的论据。在这种情况下,从正式的角度来看,没有什么可以阻止实现执行以下操作:

  1. 首先 move -构造一对tmp从你的论点(这意味着你不能在函数返回后对你的论点的状态做出假设);
  2. 检查键是否已经存在于 map 中;
  3. 如果不是,请进行必要的清理以插入 tmp放入容器中。

甚至:

  1. 检查键是否存在于映射中;
  2. 如果是这样,插入一个根据你的论点 move 构造的新元素;
  3. 如果不是,则根据您的论点 move 构造一个新对象,并且不对其进行任何操作。

上面的第3点是绝对没有意义的,但并没有正式禁止。注意措辞:

Inserts a value_type object t constructed with std::forward<Args>(args)... if and only if there is no element in the container with key equivalent to the key of t.

这只是说如果容器中没有元素的键等于t的键, 没有对象从 t move 构造将被插入到 map 中 - 但是,对于这听起来多么愚蠢,它并没有说根本没有对象应该从t move 构造。 : 只要它不被插入 map ,这是允许的。

这就是说,由于标准在这方面没有明确限制实现,因此您不能假设您的论点是否被移出。因此,您不能假设函数调用返回时您的对将处于的状态(根据第 17.6.5.15 段)。

虽然我可以让个人意见潜入,但我认为这是一个缺陷。

关于c++ - 将其 move 到 map 后访问一对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17552191/

相关文章:

c++ - STL 中的随机元素在 log n 中设置/映射

c++ - 使用 std::enable_if 时如何拆分声明和实现

map - 为什么我的unordered_map自己订购?

c++ - 从 map 容器中查找第一个大于用户指定值的值

c++ - MFC C++ 在树控件中填充数据

c++ - 链表析构函数 C++

c++ - 如何调用绑定(bind)了所有参数的 boost::function 对象

c++ - 取代表开始/结束的数字对,并消除重叠

c++11 - 使用 valgrind Massif 工具,未创建结果文件

r - 如何在 R 中使用 map ?