C++ Unknown number of arguments.

Started by
3 comments, last by mrwonko 13 years, 3 months ago
Below is a mock up of what I'm trying to make better.

I have a object (House) which takes a number of other objects (Cat) in it's constructor. The number of objects it takes is unknown but there is a maximum number. The order the Cats are placed in the constructor is important as they will be acted on in that order. Currently, I'm default filling them. I had thought of using a vector in the House parameter list but there are several hundred possibilities and I'm not sure I'd want to generate a vector for each of them. Creating a function which generates a vector based on Cat objects seems to run into the same problem as the House Constructor.

Ultimately, what happens is a vector of Houses is constructed. However, only one of them is selected for use later. Once selected the Cat objects it holds are acted upon. Is there a better way?

Thanks.

class House
{
public:
House(const Cat& a = Cat(), const Cat& b = Cat(), const Cat& c = Cat(),
const Cat& d = Cat(), const Cat& e = Cat(), const Cat& f = Cat())

{
if (a.isValid() == true) m_vCats.push_back(a);
if (b.isValid() == true) m_vCats.push_back(B);
if (c.isValid() == true) m_vCats.push_back(c);
if (d.isValid() == true) m_vCats.push_back(d);
if (e.isValid() == true) m_vCats.push_back(e);
if (f.isValid() == true) m_vCats.push_back(f);
}

private:

std::vector m_vCats;

};



int main()

{
Cat felix( Cat("felix") );
Cat morris( Cat("morris") );
Cat slyvester( Cat("sylvester") );
Cat fluffy( Cat("fluffy") );
Cat garfield( Cat("garfield") );
Cat heathcliff( Cat("heathcliff") );
Cat eric( Cat("eric the cat") );

std::vector vHouses;
vHouses.push_back( House(felix) );
vHouses.push_back( House(felix, garfield) );
vHouses.push_back( House(felix, heathcliff) );
vHouses.push_back( House(morris, slyvester) );
vHouses.push_back( House(eric, morris, garfield, slyvester) );
vHouses.push_back( House(felix, morris, eric, fluffy, garfield) );
vHouses.push_back( House(morris, felix, eric, fluffy, garfield) );

// Blah blah blah
// Do some stuff with one of the elements of vHouses.

}
Advertisement
If your compiler supports them, you could use variadic templates, but this is unfortunately rather uncommon right now. You could manually create overloads from one to six arguments, though this would be a pain. Alternately you could use something like boost::preprocessor to create the overloads for multiple arguments.
You could overload operator << to be
House &operator <<( House &h, const Cat &c ) { h.add_cat( c ); return h; }
And create an add_cat function
void House::add_cat( const Cat &c ) { m_vCats.push_back( c ); }
Then your add section would look like:
vHouses.push_back( (House() << morris << felix << eric << fluffy << garfield) );
I don't know if that is uglier or not, but the << and >> operators tend to be overloaded in C++ for stream operations where (...) would be used in C.

Tangental note:
Cat felix( Cat("felix") );
Should probably be written as just
Cat felix("felix");:
The first way creates a temporary Cat, then copies it into felix. The second one just initializes felix.

You could overload operator << to be
House &operator <<( House &h, const Cat &c ) { h.add_cat( c ); return h; }
And create an add_cat function
void House::add_cat( const Cat &c ) { m_vCats.push_back( c ); }

If you made operator<< a member function instead of a free function (and a free function seems unnecessary in this case) then you won't need to create add_cat because operator<< will be able to do m_vCats.push_back( c ); directly instead of indirectly

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

In some classes of Luabind the "," operator is overloaded to support variable numbers of arguments. I didn't even know that was possible.

This topic is closed to new replies.

Advertisement