简体   繁体   English

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

[英]Why doesn't this use of emplace_back with deleted copy constructor work?

I have a type that I have deleted the copy constructor from, and I would like to have a vector of this type, so I need to create all the elements via emplace_back . 我有一个类型,我已经删除了复制构造函数,我想有一个这种类型的vector ,所以我需要通过emplace_back创建所有元素。 But, emplace_back seems to require a copy constructor, as the compiler gives a warning about not being able to instantiate emplace_back because the copy constructor has been deleted. 但是, emplace_back似乎需要一个复制构造函数,因为编译器会发出警告,因为复制构造函数已被删除,因此无法实例化emplace_back Why does it need a copy constructor? 为什么需要复制构造函数? I thought the whole point of emplace_back was to build the vector without copying anything. 我认为emplace_back是构建vector而不复制任何东西。 Can I even have a vector of objects that don't have a copy constructor? 我甚至可以拥有一个没有复制构造函数的对象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);
}

Compiler is clang/llvm. 编译器是clang / llvm。

When the vector 's internal storage grows, it will need to move the elements from the old storage to the new. vector的内部存储增长时,需要元素从旧存储移动到新存储。 By deleting the copy constructor, you also prevent it generating the default move constructor. 通过删除复制构造函数,还可以防止它生成默认移动构造函数。

To be able to call emplace_back, your type should either be EmplaceConstructible or MoveInsertible . 为了能够调用emplace_back,您的类型应该是EmplaceConstructibleMoveInsertible You need to give a move constructor to your class if you have deleted the copy constructor. 如果删除了复制构造函数,则需要为类提供移动构造函数。 (Check this for requirements of emplace_back) (检查是否有emplace_back的要求)

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

If you try to run this code: 如果您尝试运行此代码:

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

You will get the following result: 您将获得以下结果:

constructed from array 从数组构造

Live Demo 现场演示

It is clear that just the constructor from std::Array is called. 很明显,只调用std::Arrayconstructor So, no need for copy constructor . 所以,不需要copy constructor But in the same time if you deleted the copy constructor , the compiler will raise an error (at least on two compilers I tried first second ). 但如果你同时deletedcopy constructor ,编译器会产生一个错误(至少在两种编译器我想第一 第二 )。 I think that some compilers will check for the existence of copy constructor when using emplace_back even if it is not necessary in this practical case while others won't. 我认为一些编译器在使用emplace_back时会检查是否存在copy constructor ,即使在这种实际情况下没有必要,而其他编译器也不会。 I do not know what is standard here (which compiler is right or wrong). 我不知道这里的标准是什么(哪个编译器是对还是错)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM