简体   繁体   English

为什么这个std :: vector :: emplace_back会失败?

[英]Why does this std::vector::emplace_back fail?

I'm coming across a compiler error that says: 我遇到一个编译错误,说:

attempting to reference a deleted function 试图引用已删除的功能

#include <iostream>
#include <vector>

template <typename T>
struct Container
{
    Container() = default;
    Container(const Container& other) = delete;
    Container(T* ptr) : ptr(ptr) {}
    T* ptr;
    ~Container() { delete ptr; }

};

struct Foo { Foo(int a, int b) {} };

int main()
{
    std::vector<Container<Foo>> myvector;
    myvector.push_back(new Foo(1, 2)); // I understand why this doesn't work.
    myvector.emplace_back((new Foo(1, 2))); // I don't understand why this fails

}

I understand why it says attempting to reference a deleted constructor when I do std::vector::push_back() , because this does a copy and needs to call the copy constructor , which I deleted. 我理解为什么当我执行std::vector::push_back()时它试图引用已删除的构造函数 ,因为这会复制并需要调用我删除的复制构造函数

But std::vector::emplace_back() is supposed to take the constructor arguments of the type it holds. 但是std::vector::emplace_back()应该采用它所拥有的类型的构造函数参数。 When I emplace back, I give it a pointer to a Foo , and this should be forwarded to the Container::Container(T* ptr) constructor. 当我向后移动时,我给它一个指向Foo的指针,这应该被转发到Container::Container(T* ptr)构造函数。

What am I missing? 我错过了什么?

Declaring a User-Defined copy constructor will not define an implicit move constructor ; 声明用户定义的复制构造函数不会定义隐式移动构造函数 ; T must either have a copy constructor or a move constructor to push_back or emplace_back* an object into a std::vector<T> . T必须具有复制构造函数移动构造函数 to push_backemplace_back*对象到std::vector<T>

From the docs , see the requirements on T to instantiate a std::vector<T> . 文档中 ,参见T的要求来实例化std::vector<T> (No restriction here, read on) .. emphasis mine (这里没有限制,请继续阅读)。 强调我的

The requirements that are imposed on the elements depend on the actual operations performed on the container . 对元素施加的要求取决于对容器执行的实际操作 Generally, it is required that element type meets the requirements of Erasable, but many member functions impose stricter requirements . 通常,要求元素类型满足Erasable的要求, 但许多成员函数强加了更严格的要求 This container (but not its members) can be instantiated with an incomplete element type if the allocator satisfies the allocator completeness requirements. 如果分配器满足分配器完整性要求,则可以使用不完整的元素类型实例化此容器(但不是其成员)。

From std::vector<...>::push_back : 来自std::vector<...>::push_back

Type requirements 类型要求

  • T must meet the requirements of CopyInsertable in order to use overload (1). T必须满足CopyInsertable的要求才能使用overload(1)。
  • T must meet the requirements of MoveInsertable in order to use overload (2). T必须满足MoveInsertable的要求才能使用overload(2)。

From std::vector<...>::emplace_back : 来自std::vector<...>::emplace_back

Type requirements 类型要求

  • T (the container's element type) must meet the requirements of MoveInsertable and EmplaceConstructible . T (容器的元素类型)必须满足MoveInsertableEmplaceConstructible的要求。

For emplace_back here, your code would fulfill the EmplaceConstructible criteria, however, because reallcations can happen, you must equally fulfill MoveInsertable . 对于emplace_back ,您的代码将满足EmplaceConstructible标准,但是,因为可能会发生reallcations,所以您必须同样满足MoveInsertable

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

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