Variadic construction for initialising vector of unique_ptr to base type

点点圈 提交于 2019-12-08 05:50:43

问题


Below is an example program where a 'Container' class needs to store a list of 'Items' via a base class pointer. Having started with C++11/14 the natural choice would be to use std::unique_ptr and variadic templates in the case I have.

However being new I cannot fathom how to convert the variadic list into and initialiser list for the vector of unique_ptr in a manner that compiles. Help is greatly appreciated as I have failed to find anything online that helps me with this issue so far (albeit likely out there!).

Thanks in advance:

// Example program
#include <iostream>
#include <string>
#include <memory>
#include <vector>

struct Item
{
};


struct Container
{
    template<typename... Items>
    Container( Items&&... items ) 
    : items_( {std::make_unique<Items>(items)...} ) //<<TODO: How, VC compiler times out with this code!?
    {
    }

    std::vector<std::unique_ptr<Item>> items_;
};

struct A : Item { A(float){}  };
struct B : Item {  };
struct C : B    { C(float){} };
struct D : Item { D(float){} };

int main()
{
  Container x( A(1), C(2), D(3) );

  return 0;
}

回答1:


The issue is that you cannot move unique_ptr out from intializer_list. Read this question for more details.

This solution use the technique in this answer that instead of using intializer_list, you can use plain array to construct items.

struct Container
{
    template<typename... Items>
    Container( Items&&... items ) 
    : items_()
    {
        std::unique_ptr<Item> itemArr[] = {std::make_unique<Items>(std::move(items))...};
        items_ = std::vector<std::unique_ptr<Item>> {std::make_move_iterator(std::begin(itemArr)), std::make_move_iterator(std::end(itemArr))};
    }

    std::vector<std::unique_ptr<Item>> items_;
};

Online Demo



来源:https://stackoverflow.com/questions/33747131/variadic-construction-for-initialising-vector-of-unique-ptr-to-base-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!