1

I have a base class

template<class T>
class Base
{
public:
    Base(T foo = T())
    {
        for(int i = 0; i < 10; i++)
            foos.push_back(foo);
    }

private:
    std::vector<T> foos;
}

and I have a derived class

class Derived : public Base<Bar>
{
public:
    Derived() : Base(Bar("somerandomparameter")) {}
}

What I want this to do, is to create a vector of 10 new Bars all with the provided constructor (whatever it is).

I thought of creating a custom copy constructor but this did not work as expected because it seems like the push_back method creates some more copies, at least my Bar constructor get's called more than 10 times.

The optimal solution to me would be something like passing a list of parameters as this is only creating the 10 objects I want.

...
Base(ParameterList l)
{
    for(int i = 0; i < 10; i++)
        foos.push_back(T(l));
}
...

But since this is a template class, I need that list to be adaptive to whatever type or number of parameters T needs. Is there a way of doing that or do you know of an even better way of doing what I want to do?

po0l
  • 98
  • 8
  • 1
    C++11 accepts [variadic templates](http://en.cppreference.com/w/cpp/language/parameter_pack). You may specify the standard c++ – BiagioF Nov 19 '17 at 11:54

1 Answers1

4

A template class can have a further templated constructor. In your case you need one that accepts a parameter pack and does (non-perfect) forwarding:

template<class T>
class Base
{
  std::vector<T> foos;

public:
    template<typename... Args>
    Base(Args&&... args)
    {
        foos.reserve(10);
        for(int i = 0; i < 10; i++)
            foos.emplace_back(args...);
    }  
};

And that should do it. Just pass the parameters to the constructor of Base<Bar> in your Derived class's constructor.

The reason I emphasize the non-perfect forwarding is that should we std::forward the arguments into the first item that is inserted, it may move them, thus rendering them invalid for the second. YMMV, and you should consider this carefully.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • Wow, thank you very much! It works like a charm! And could you explain that last paragraph to a beginner like me? ;) I don't quite get what forwarding is (Only that it has something to do with l- and rvalues?) – po0l Nov 19 '17 at 12:10
  • @po0l - The call to reserve is so that there would be space for 10 elements from the start. That way the vector doesn't have to reallocate enything when we insert. My last paragraph deals with the [implications of perfect forwarding](https://stackoverflow.com/questions/3582001/advantages-of-using-forward). I'm afraid it's a bit too wide a subject to broach in comments. Nor is it relevant to your immediate question. – StoryTeller - Unslander Monica Nov 19 '17 at 12:12
  • Well, thank you anyway. You're right, it is not immediately necessary for my problem but it's the way I am I want to understand things I don't understand yet ;). I'll look in the internet! – po0l Nov 19 '17 at 12:15