vendredi 28 octobre 2016

Pass a list of deriveds for storage as member

I have a class widget.
I have an abstract class base with derivates derived_a, derived_b, etc.

I want widget to hold an arbitrary amount of objects that are derivated from base in order to later use them polymorphically.

My first attempt looks like this:

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

class widget {
public:
    explicit widget(std::vector<std::unique_ptr<base>>&& params) :
    members {std::move (params)}
    {            
    }

private:
    std::vector<std::unique_ptr<base>> members;
};

And would be called like this:

std::vector<std::unique_ptr<base>> v;
v.push_back(std::move(std::make_unique<derived_a>()));
widget w (std::move(v));

However, this solution seams unnessesarry verbose and not user friendly at all, especially when providing multiple types:

std::vector<std::unique_ptr<base>> v;
v.push_back(std::move(std::make_unique<derived_a>()));
v.push_back(std::move(std::make_unique<derived_b>()));
v.push_back(std::move(std::make_unique<derived_c>()));
v.push_back(std::move(std::make_unique<derived_a>()));
v.push_back(std::move(std::make_unique<derived_b>()));
v.push_back(std::move(std::make_unique<derived_c>()));
widget w {std::move(v)};

Instead, I would prefer usage along the lines of

widget w {derived_a(), 
          derived_b(), 
          derived_c(), 
          derived_a(), 
          derived_b(), 
          derived_c()};

so that widget is provided with a list of rvalues that it then can turn into std::vector<unique_ptr<base>>.
I have the impression that this can be achieved through templating the ctor, but, despite intensive googling, I have no clue on how to achieve my goal exactly.

Please note that the class template solution that would look tike this:

widget<derived_a, 
       derived_b, 
       derived_c, 
       derived_a, 
       derived_b, 
       derived_c> w;

Is undesirable, as I need to provide some deriveds with parameters.

Aucun commentaire:

Enregistrer un commentaire