20

我有一个类型,我从中删除了复制构造函数,我想拥有一个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。

4

3 回答 3

31

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

于 2015-12-31T09:05:35.877 回答
12

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

 MyType(MyType &&a) {/*code*/} //move constructor
于 2015-12-31T09:06:37.893 回答
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);
}

您将得到以下结果:

从数组构造

现场演示

很明显,只调用了constructorfrom 。std::Array所以,不需要copy constructor. 但与此同时,如果您deleted使用copy constructor,编译器将引发错误(至少在我尝试过的两个编译器 。我认为一些编译器会在使用 emplace_back 时检查是否存在,即使在这种实际情况下没有必要,而其他编译器则不需要。我不知道这里的标准是什么(哪个编译器是对还是错)。copy constructor

于 2015-12-31T09:18:18.663 回答