I'm stuck with C++03 for now, and I want to create a global function that accepts any number of type-safe arguments (up to a reasonable limit if necessary, like 9).
I have access to the full boost library in my code base, so I'm hoping boost::mpl::vector
can be useful here. I also don't want this to be too inconvenient to write. Syntax at the call site should be simple like so:
LogDebugMessage("Number of cats and dogs:", m_myPets->NumCats(), m_myPets->NumDogs());
What would be the best way to implement this, in a type safe way?
EDIT
I also realize I could use template specialization for this, but I don't want to end up defining the same struct 9 times, one for each additional template parameter. That's just too messy for this. I'd like to avoid that if at all possible.
The best way would be 9 overloads. :P
The easiest way for you, however, would rather be boost::tuple
instead of using boost::mpl
, since mpl
is mostly compile-time only. The call site (user) would then write something like
LogDebugMessage("Number of cats and dogs:",
boost::tie(m_myPets->NumCats(), m_myPets->NumDogs()));
tie
creates a tuple of references. Or if the call involves temporaries:
LogDebugMessage("Number of cats, dogs and birds:",
boost::make_tuple(m_myPets->NumCats(), m_myPets->NumDogs(), 0));
If the logged types are a bit heavier (boost::make_tuple
makes copies), you can resort to good old boost::ref
.
Your LogDebugMessage
would then look something like this:
template<class Tuple>
void LogDebugMessage(std::string const& msg, Tuple const& args);
And after that you'd unpack the tuple using recursion similar to my tuple printer. Note that only operator<<
actually uses variadic templates, and only does so to just pick up std::tuple
. You would most likely only use the print_tuple
part.