Если вы просто хотите вывести параметры, можно использовать функцию шаблонов с переменными параметрами - предлагая безопасность типов, которой нет у функций с переменными параметрами ...
void print() { }
template <typename T, typename ... TT>
void print(T&& t, TT&& ... tt)
{
std::cout << std::forward<T>(t) << ' ';
print(tt...);
}
template <typename F, typename ... TT>
void execute(F f, TT&& ... tt)
{
std::cout << "calling function with arguments: ";
print(std::forward<TT>(tt)...);
std::cout << std::endl;
f(std::forward<TT>(tt)...);
}
Если вы разрешите немного предварительномагия компилятора, мы даже могли бы включить имя функции:
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)
Пример использования здесь ...
Это немного похоже на обходной путь (конечно, вынужен еще один вызов функции, и лямбды могут выглядеть уродливо), но вы получите результат с помощью чистых средств C ++ и без уродливых уловок (возможно, кроме макроса).