Reputation: 4990
Without using variadic function, is it possible to loop over a function's arguments?
This would help me in my question gcc instrumentation - is it possible to automatically output the arguments of a function?
Upvotes: 2
Views: 101
Reputation: 25536
If you just want to output the parameters, a variadic template function could do the trick – offering the type safety a variadic function is lacking...
void print() { }
template <typename T, typename ... TT>
void print(T const& t, T const& ... tt)
{
std::cout << t << ' ';
print(tt...);
}
template <typename F, typename ... TT>
void execute(F f, TT&& ... tt)
{
std::cout << "calling function with arguments: ";
print(tt...);
std::cout << std::endl;
f(std::forward<TT>(tt)...);
}
Even more elegant, if C++17 is available, is a fold expression:
template <typename F, typename ... TT>
void execute(F f, TT&& ... tt)
{
std::cout << "calling function with arguments: ";
char const* comma = "";
((std::cout << comma << tt, comma = ", "), ...);
std::cout << std::endl;
f(std::forward<TT>(tt)...);
}
Note how here modifying the comma
variable allows to separate the arguments in the output string by commas without adding a trailing one.
If you allow a bit of pre-compiler magic, we even could include the function name:
template <typename F, typename ... TT>
void execute_(F f, char const* name, TT&& ... tt)
{
std::cout << "calling function '" << name << "' with arguments: ";
// ...
}
#define execute(FUNCTION, ...) execute_(FUNCTION, #FUNCTION, ## __VA_ARGS__)
// be aware of GCC extension: ^^
// catching empty arguments list!
// alternative variant, not relying on extensions but requiring C++20:
#define execute(F, ...) execute_(F, #F __VA_OPT__(,) __VA_ARGS__)
Usage example here (including a print
variant not relying on an empty base function: print2
)...
It has a bit a taste of workaround (sure, you need another function call and1 lambdas might look ugly), but you get the result with pure C++ means and no ugly tricks – apart from the macro, obviously; given variant relies on a GCC extension.
1Not any more with the fold expression.
Upvotes: 1