vector<unique_ptr> 的初始化失败并出现复制错误

Posted

技术标签:

【中文标题】vector<unique_ptr> 的初始化失败并出现复制错误【英文标题】:Initialization of vector<unique_ptr> fails with copy error 【发布时间】:2017-04-09 17:40:02 【问题描述】:

我正在努力正确初始化std::vectorstd::unique_ptr

示例代码:

#include <iostream>
#include <vector>
#include <memory>

class Base
    public:
        std::string getString()  return this->string; ;
    protected:
        std::string string;
;
class Derived: public Base
    public:
        Derived(std::string bla)
            this->string = bla;
    
;
class Collection
    protected:
        std::vector<std::unique_ptr<Base>> mappings;
;
class DerivedCollection: public Collection
    public:
        DerivedCollection(std::string bla)
            std::vector<std::unique_ptr<Base>> maps;
            maps.push_back(std::make_unique<Derived>(bla));
            //or this: (does not work aswell)
            //maps.emplace_back(new Derived(bla));
            this->mappings = maps;
        
;

int main(int argc, char** argv)
    DerivedCollection test = DerivedCollection("bla");
    return 0;

不知何故,仅定义 mappings 会触发错误:

/usr/include/c++/6.3.1/bits/stl_construct.h:75:7: 
error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Base; _Dp = std::default_delete<Base>]’
  ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); 

这告诉我,我以某种方式设法从 const unique_ptr 构造了一个 unique_ptr,但由于 unique_ptr 不是可复制构造的,所以它不起作用。

即使我注释了 DerivedCollection 构造函数中的所有内容,这仍然会失败。

我的猜测是我需要一个适合 Collection 类的构造函数。我不确定如何定义它。

有什么想法吗?

-- 麦芽糖

【问题讨论】:

【参考方案1】:

maps 是不可复制的,因为它是unique_ptrvector。将其移至 mappings 即可解决问题:

this->mappings = std::move(maps);

live wandbox example


您的代码还有其他问题:

您应该使用成员初始化列表来初始化数据成员,而不是构造函数体

getString 可以返回 const std::string&amp; 以避免复制。

Derived的构造函数可以std::movebla进入数据成员。

test 可以如下初始化:DerivedCollection test"bla"

永远不要使用new - 请改用make_unique

【讨论】:

或者,std:swap(mappings, maps) 哇,这很简单。关于其他问题:这只是我在大约 30 秒内整理的一个简单示例,因此可以解释这种草率的风格。此外,这个问题出现在我需要非平凡构造函数逻辑的上下文中,这就是我没有使用初始化列表的原因。不过感谢您的提示!

以上是关于vector<unique_ptr> 的初始化失败并出现复制错误的主要内容,如果未能解决你的问题,请参考以下文章

vector系列--vector<unique_ptr<;;初始化(所有权转移)

使用 C++11 for() 循环遍历 vector<unique_ptr<mytype>>

在 std::vector<T> 和 std::vector<unique_ptr<T>> 上均匀迭代

调整 std::vector<std::unique_ptr<T>> 大小的性能

boost::ptr_vector 与 std::vector<std::unique_ptr<T>>? [关闭]

如何调整 std::vector<std::queue<std::unique_ptr<int>>> 的大小?