是否可以创建一个std :: vector <std :: unique_ptr <bar>&gt;使用填充构造函数?

时间:2016-01-15 06:48:37

标签: c++ c++11 vector stl unique-ptr

我有一个类Foo,其成员变量类型为std::vector<std::unique_ptr<Bar>>,我想填写此类构造函数的初始化列表。这可能吗?

我希望使用vector的fill构造函数是可能的,就像这样

Foo::Foo(int n):
    vector<unique_ptr<Bar>> (n, unique_ptr<Bar> (new Bar))
{}

但我认为这需要std::unique_ptr的复制构造函数,它被删除(应该是)(unique_ptr(const unique_ptr&) = delete)。

有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:4)

由于它不可复制,请移动它!

使用硬编码对象的解决方案:

#include <memory>
#include <vector>
#include <iterator>
class Bar{};
class Foo{
    public:
    Foo():bars(get_bars()) {}
    std::vector<std::unique_ptr<Bar>> bars;

    private:
    std::vector<std::unique_ptr<Bar>> get_bars(){
        std::unique_ptr<Bar> inilizer_list_temp[]={std::make_unique<Bar>(),std::make_unique<Bar>(),std::make_unique<Bar>()};
        return  std::vector<std::unique_ptr<Bar>>{std::make_move_iterator(std::begin(inilizer_list_temp)),std::make_move_iterator(std::end(inilizer_list_temp))};
    }
};
int main()
{
    Foo foo;
}

Live Demo

具有动态对象数量的解决方案:

#include <memory>
#include <vector>
#include <iterator>
#include <iostream>
class Bar{
    public:
    int a=5;
    };
class Foo{
    public:
    Foo():bars(get_bars(10)) {}
    std::vector<std::unique_ptr<Bar>> bars;

    private:
    std::vector<std::unique_ptr<Bar>> get_bars(int n){
        std::vector<std::unique_ptr<Bar>> inilizer_list_temp;
        inilizer_list_temp.reserve(n);
        for(size_t i=0;i<n;++i){
            inilizer_list_temp.emplace_back(std::make_unique<Bar>());
        }
        return inilizer_list_temp;
    }
};
int main()
{
 Foo foo;
 for(auto const& item:foo.bars){
     std::cout << item->a;
 }
}

Live Demo

有关详细信息Can I list-initialize a vector of move-only type?

,请参阅此处

修改

对于没有std :: make_uniuqe的C ++ 11用户:

template<typename T, typename ...Args>
std::unique_ptr<T> make_unique( Args&& ...args )
{
    return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) );
}

Source