Reputation: 4014
Is it possible to write a macro which can take in a variable number of arguments and expands like this :
quickdebug(a) -> cout << #a ": " << a;
quickdebug(a,b) -> cout << #a ": " << a << #b ": "<< b;
etc
If not, is it possible for me to at least print all the arguments without giving format strings. e.g
quickdebug2(a) -> cout << a ;
quickdebug2(a,b) -> cout << a << " " << b ;
etc
For example in java I can write a function which provides me similar functionality:
void debug(Object...args)
{
System.out.println(Arrays.deepToString(args));
}
Upvotes: 3
Views: 2114
Reputation: 2389
By using a class that overrides , operator:
class VariadicToOutputStream
{
public:
VariadicToOutputStream(std::ostream& s, const std::string& separator = " ") : m_stream(s), m_hasEntries(false), m_separator(separator) {}
template<typename ObjectType>
VariadicToOutputStream& operator , (const ObjectType& v)
{
if (m_hasEntries) m_stream << m_separator;
m_stream << v;
m_hasEntries=true;
return *this;
}
~VariadicToOutputStream()
{
m_stream << std::endl;
}
private:
std::ostream& m_stream;
bool m_hasEntries;
std::string m_separator;
};
You can write for instance:
VariadicToOutputStream(std::cout) , 1, 0.5f, "a string";
This can then be wrapped with a preprocessor macro:
#define VARIADIC_TO_STDOUT(...) VariadicToOutputStream(std::cout),__VA_ARGS__;
So you can write:
VARIADIC_TO_STDOUT(1, 0.5f, "a string");
It would be easy to add f.i. separator strings to be used between arguments.
Edit: I just added a default space as separator string.
Upvotes: 7
Reputation: 7230
It is possible to make a macro that is variadic thus taking a variable amount of arguments. The syntax is similar to that of a function:
#define quickdebug(...) functiontocall("test", __VA_ARGS__)
Any argument listed after the last named argument in the argument list will be listed in __VA_ARGS__
including any seperating comma.
So: quickdebug(1, 2, "123", 4.5)
becomes functioncall("test", 1, 2 , "123", 4.5)
However at some point you need to use these arguments, and here it can become extremely difficult if you don't have a format string, or something else indicating the type of the arguments.
The problem is that when reading variables from a variable arguments list, you need to know the type of the argument, or at least its size. If I were you I would choose a different approach.
You can read more about variadic macros here: http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
Upvotes: 1