为什么要在向量末端放置一个类型T需要移动可构造?

Cpp*_*oob 2 c++ move stdvector move-semantics c++11

为什么公共构造函数(和析构函数)不足以将类型的对象T放在向量的后面?以下片段格式不正确.

#include <vector>

struct Foo {
  Foo() {}
  Foo(int) {}
  ~Foo() {}

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

int main() {
  std::vector<Foo> vfoo(10);

  vfoo.emplace_back();
}
Run Code Online (Sandbox Code Playgroud)

emplace_back要求,Foo至少可以移动构造的,而这个代码无法编译,因为移动构造函数与拷贝构造函数一起被删除.但我想像emplace_back使用placement new调用默认构造函数.

Yak*_*ont 7

10在您的示例中,向量由元素构成.

然后你添加一个.如果没有更多空间capacity(),则必须分配一个新缓冲区,必须将10个元素移入其中,然后附加新元素.

你会注意到move上面这个词- 这就是你需要移动ctor的原因.

更重要的是,即使你没有元素,或者你仔细确保有足够的容量,编译器也无法知道:移动现有元素的代码将被编译(如果没有运行),你将得到你的错误.

缺少"推回,我保证已有容量"的方法vector.那,加上"设置容量,丢弃任何现有元素"将允许您添加元素而无需移动ctor(或复制ctor后备).直到emplace被发明,所有添加元素都需要复制或移动:直到C++ 11所有添加元素都需要副本.缺少这两种具有奇怪语义的方法只是为了让一个不可移动的类型限制使用a vector并不奇怪.

我鼓励你编写一个具有这两个扩展(或类似的东西)的容器,并建议将它添加到C++中:它也可能有助于高性能用例(编译器可以证明我确实确保容量足够我的经验).