c++ - std::map 中键/值类型的复制/移动要求?

标签 c++ c++11

这段代码让我很困惑:

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;
}

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

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

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

最佳答案

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

实际 map 对象在运行时是否为空并不重要,因为这些纯粹是静态考虑,完全由对象的类型决定。

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

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

(对于所有以适当方式管理动态内存的容器来说,这应该是正确的,例如通过 std::allocator<value_type> ,但对于像 std::array 这样的东西当然不正确,无论是否如此,这都会很有趣它将持续 std::dynarray ,并且正如@Jonathan Wakely 所指出的,如果分配方案无法批量移动节点。)

关于c++ - std::map 中键/值类型的复制/移动要求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17603666/

相关文章:

c++ - 如何在 C++ 中创建一个构造函数来创建线程开始运行时应该返回的 pthread

c++ - 使用可变模板参数构建枚举

c++ - 所有线程都做同样的事情。程序文件

c++ - 解释 Python 扩展多线程

c++ - 在切换循环周期结束时未显示的游戏总数

c++ - wmi 和 API 有什么不同

c++ - 在 lambda 中捕获完美转发的变量

c++ - 为每个可变参数模板参数和一个数组调用一个函数

c++ - 错误 "function call missing argument list"- 帮我指明正确的方向

c++ - 字符串迭代器不兼容