c++ - 创建 move 构造对象的 vector

标签 c++ move stdvector unique-ptr emplace

我有一个类,其中包含一个构造函数,该构造函数在构造过程中 move 对象:

class SomeClass
{
private:
    const std::unique_ptr<Base> foo;

public:
    template <typename T>
    inline explicit SomeClass(T&& derived) noexcept
     : foo(std::make_unique<T>(derived))
    {
        static_assert(std::is_base_of<Base, T>::value);
    }
};

当我只需要一个实例时,可以毫无问题地构造该类的对象:

class Derived : public Base
{
    // ...
};

Derived bar(...);
SomeClass baz(std::move(bar));

// Or

SomeClass baz(Derived(...));

但是,我无法将 SomeClass 类型的任何对象放置(或推送)到 std::vector<SomeClass> .

std::vector<SomeClass> vec;

Derived bar(...);
vec.emplace_back(std::move(bar)); // Does not work.

vec.emplace_back(Derived(...));   // Does not work.

请您解释一下为什么无法放置物体?我以为完美转发了emplace_back使用将允许构造 SomeClass 的实例以与构造单个实例相同的方式就位。

请您也解释一下如何修改以允许构建 std::vector<SomeClass>

我的猜测是,由于构造函数参数是通过 move 传递的,因此它们不会一直转发到 emplace_back 内的构造函数。方法。

最佳答案

std::vector::emplace_back value_type 提出以下要求:

Type requirements

-T (the container's element type) must meet the requirements of MoveInsertable and EmplaceConstructible.

一个const类的成员隐式删除 move 构造函数,即 SomeClass不是MoveInsertable因为const std::unique_ptr<Base> foo .

解决方案:删除const来自foo .

struct Base {};
struct Derived : public Base {};

class SomeClass
{
private:
    std::unique_ptr<Base> foo;

public:
    template <typename T>
    inline explicit SomeClass(T&& derived)
        noexcept(std::is_nothrow_constructible_v<decltype(foo), T&&>) // (1)
     : foo(std::make_unique<T>(std::forward<T>(derived))) // (2)
    {
        static_assert(std::is_base_of<Base, T>::value);
    }
};

int main()
{
    std::vector<SomeClass> vec;

    Derived bar{};
    vec.emplace_back(std::move(bar));

    vec.emplace_back(Derived{}); 
}

Live example .

作为旁注,我建议制作 noexcept有条件取决于 std::is_nothrow_constructible (1)并通过std::forward<T>(derived)std::make_unique使用转发引用 (2)。

关于c++ - 创建 move 构造对象的 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52415574/

相关文章:

c++ - 返回一个 vector ,这里应用的是 RVO 还是 move 构造函数?

c++ - vector::clear 在 libc++ 中用于简单可破坏的类型

C++ 位集没有内联?

c++ - PutFile 不从事件目录发送文件?

c++ - 使用 vector 查找公共(public)元素的问题

c# - 平滑鼠标 move

linux - 提取名称中包含关键字的所有文件

c++ - SSE 版本的不同结果

C++: vector<字符串> *args = new vector<字符串>();导致SIGABRT

c++ - 在恒定时间内交换 std::vector 的内容——这可能吗?