4

I'm making a class - let's call it Container - that is basically just containing a std::vector and some special logic that decides how are the vector values picked. I want to add a method for adding multiple values to my class with one call. This is my method that adds one item:

void LoopGenerator::add(RandomStripe &stripe)
{
    stripes.push_back(new SingleStripe(stripe));
}

I'd like a similar method that would be called like this:

LoopGenerator gen = LoopGenerator();
gen.add(RandomStripe(), RandomStripe(), RandomStripe() ... and as much as you want ... );

and would add all parameters to the inner std::vector.

Is this possible to do just with standard libraries, or best without them?

Tomáš Zato
  • 50,171
  • 52
  • 268
  • 778
  • 1
    A traditional va_args would require some way to know how many parameters were passed. Alternatively, you can use variadic templates, if available. – Raymond Chen Dec 05 '14 at 21:03
  • @Tomáš Zato What are RandomStripe and SingleStripe? Are they different types? – Vlad from Moscow Dec 05 '14 at 21:07
  • @VladfromMoscow Yes, they are different. Actually, `SingleStripe` just exists so `RandomStripe` can be with array along with other stripe generating classes... `SingleStripe` derives from same class as `LoopGenerator`. – Tomáš Zato Dec 05 '14 at 21:26

2 Answers2

5

You can use std::initializer_list. For example

#include <initializer_list>
#include <algorithm>
#include <vector>
#include <iterator>    


//...

void LoopGenerator::add( std::initializer_list<RandomStripe> stripe )
{
    std::transform( stripe.begin(), stripe.end(), 
                   std::back_inserter( stripes ),
                   []( const RandomStripe &s ) { return new SingleStripe( s ); } );
}

And call it like

gen.add( { RandomStripe(), RandomStripe(), RandomStripe(), /*...*/ } );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

If you have C++11 you could utilize variadic templates to accomplish this.

In prior versions I would suggest just doing method chaining:

LoopGenerator& LoopGenerator::add(RandomStripe &stripe)
{
    stripes.push_back(new SingleStripe(stripe));
    return *this;
}

And call it gen.add(RandomStripe()).add(RandomStripe()).add(RandomStripe());

Mark B
  • 95,107
  • 10
  • 109
  • 188