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

Why does this std::vector::emplace_back fail?

本文关键字:back 失败 vector std 为什么 emplace      更新时间:2023-10-16

我遇到了一个编译器错误,上面写着:

尝试引用已删除的函数

#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
}

我理解为什么当我做std::vector::push_back()时它说试图引用已删除的构造函数,因为这会执行复制并且需要调用我删除的复制构造函数

但是std::vector::emplace_back()应该采用它所持有的类型的构造函数参数。当我放置回来时,我给它一个指向Foo的指针,这应该转发给Container::Container(T* ptr)构造函数。

我错过了什么?

声明用户定义的复制构造函数不会定义隐式移动构造函数;T必须具有复制构造函数移动构造函数才能push_back对象或将对象emplace_back*std::vector<T>中。

从文档中,请参阅实例化std::vector<T>T要求。(这里没有限制,请继续阅读)..强调我的

对元素施加的要求取决于对容器执行的实际操作 。通常,要求元素类型满足可擦除的要求,但许多成员函数提出了更严格的要求。如果分配器满足分配器完整性要求,则可以使用不完整元素类型实例化此容器(但不是其成员)。

std::vector<...>::push_back

类型要求

  • T必须满足CopyInsertable的要求才能使用重载 (1)。
  • T必须满足MoveInsertable的要求才能使用重载 (2)。

std::vector<...>::emplace_back

类型要求

  • T(容器的元素类型)必须满足MoveInsertableEmplaceConstructible的要求。

对于此处的emplace_back,您的代码将满足EmplaceConstructible标准,但是,由于可能会发生现实,因此您必须同样满足MoveInsertable