为什么这个使用emplace_back与删除的拷贝构造函数不起作用?

时间:2015-12-31 09:03:14

标签: c++ constructor stdvector emplace

我有一个类型,我已经删除了复制构造函数,我希望有一个vector这种类型,所以我需要通过emplace_back创建所有元素。但是,emplace_back似乎需要一个复制构造函数,因为编译器会发出警告,因为复制构造函数已被删除,因此无法实例化emplace_back。为什么需要复制构造函数?我认为emplace_back的重点是构建vector而不复制任何内容。我甚至可以拥有一个没有复制构造函数的vector个对象吗?

class MyType {
public:
    MyType(std::array<double, 6> a) {}
    MyType(const MyType& that) = delete;
};

int main() {
    std::vector<MyType> v;
    std::array<double, 6> a = {1,2,3,4,5,6};
    v.emplace_back(a);
}

编译器是clang / llvm。

3 个答案:

答案 0 :(得分:25)

vector的内部存储空间增长时,需要元素从旧存储移动到新存储。通过删除复制构造函数,还可以防止它生成默认的移动构造函数。

答案 1 :(得分:10)

为了能够调用emplace_back,您的类型应为EmplaceConstructibleMoveInsertible。 如果删除了复制构造函数,则需要为类提供移动构造函数。 (检查this是否有emplace_back的要求)

 MyType(MyType &&a) {/*code*/} //move constructor

答案 2 :(得分:1)

如果您尝试运行此代码:

// Example program
#include <iostream>
#include <string>
#include <array>
#include <vector>
class MyType {
public:
    MyType(std::array<double, 6> a) {
        std::cout<< "constructed from array\n";
        }
    MyType(const MyType& that){
          std::cout<< "copy\n";
    }

    MyType(MyType&& that){
          std::cout<< "move\n";
    }
};

int main() {
    std::vector<MyType> v;
    std::array<double, 6> a = {1,2,3,4,5,6};
    v.emplace_back(a);
}

您将获得以下结果:

  

从数组

构造

Live Demo

很明显,只有来自constructor的{​​{1}}才会被调用。所以,不需要std::Array。但是在同一时间copy constructor deleted,编译器会引发错误(至少在我试过的两个编译器上first second)。我认为一些编译器在使用emplace_back时会检查copy constructor是否存在,即使在这个实际情况下没有必要,而其他人也不会。我不知道这里的标准是什么(哪个编译器是对还是错)。