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

时间:2015-04-12 06:38:36

标签: c++ c++11 move stdvector move-semantics

为什么公共构造函数(和析构函数)不能将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();
}

emplace_back要求Foo至少可以移动构造,并且此代码无法编译,因为移动构造函数与复制构造函数一起被删除。但我想象emplace_back使用placement new来调用默认构造函数。

1 个答案:

答案 0 :(得分:7)

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

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

您会注意到上面的move一词 - 这就是您需要移动ctor的原因。

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

A&#34;推回,我保证已有容量&#34; vector中缺少方法。加上设置容量,丢弃任何现有元素&#34;会让你添加元素而不需要移动ctor(或复制ctor后备)。在发明emplace之前,所有添加元素都需要复制或移动:直到C ++ 11所有添加元素都需要副本。缺少这两个带有奇怪语义的方法只是为了让一个不可移动的类型限制使用vector并不奇怪。

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