14

这段代码让我很困惑:

struct foo {
  int i;

  foo(int j) : i(j) {}

  foo(const foo &) = delete;
  foo(foo &&) = delete;
  foo &operator=(const foo&) = delete;
  foo &operator=(foo&&) = delete;
};

bool operator<(const foo &f1, const foo &f2)
{
  return f1.i < f2.i;
}

int main(int argc, char **argv)
{
  std::map<foo,int> f;
  std::map<foo,int> f2 = f; //error (as expected)
  std::map<foo,int> f3 = std::move(f); //no error (why?)
  return 0;
}

因为我在那里没有错误,所以在移动地图时似乎没有创建关键对象(甚至没有将另一个关键对象移动到其中)。

为什么不?我可以根据 C++11 标准依赖这种行为吗?

更一般地说,键和值类型std::map的复制/移动要求是什么?在什么条件下?

4

2 回答 2

16

将一张地图复制分配到另一张地图需要复制每个项目。由于您无法复制项目,因此您无法复制分配地图。

实际地图对象在运行时是否为空无关紧要,因为这些纯粹是静态考虑,完全由对象的类型决定。

(这就像问为什么sin(0)在结果显然是整数时需要浮点单元。)

另一方面,移动整个地图很好,因为容器是基于节点的,没有实际值发生变化,只有节点发生变化。事实上,基于移动构造或移动分配节点的容器根本不需要元素是可复制的可移动的可分配的。

(对于所有以合适的方式管理动态内存的容器来说,这应该是正确的,例如 via std::allocator<value_type>,但对于类似的东西当然不是这样的std::array,它是否会适用于std::dynarray,以及@Jonathan清醒地注意到,如果分配方案无法批量移动节点。)

于 2013-07-11T21:19:03.490 回答
3

没有错误,因为只map移动,而不是map. 只分配指向元素的指针

于 2013-07-11T21:19:15.753 回答