You are calling the macro VAR
with two arguments since __VA_ARGS__
expands to the full comma separated list. But that macro just takes one argument.
What you could do is still implement this with a variadic template, but use the macro to forward variable name and value. Unfortunately it requires quite a lot of boilerplate to merge and split variadic macro arguments. I believe Boost has a library for expressing this easier, but I have never worked with it.
#define EXPAND(x) x
#define COUNT_ARGS(...) COUNT_ARGS_(__VA_ARGS__, COUNT_ARGS_RSEQ())
#define COUNT_ARGS_(...) EXPAND(COUNT_ARGS_N(__VA_ARGS__))
#define COUNT_ARGS_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N
#define COUNT_ARGS_RSEQ() 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
#define EXPAND_NAME_VALUE(argvalue, argname) argname, argvalue
#define EXPAND_ARGS(how, ...) EXPAND_ARGS_(how, COUNT_ARGS(__VA_ARGS__), __VA_ARGS__)
#define EXPAND_ARGS_(how, N, ...) EXPAND_ARGS__(how, N, __VA_ARGS__)
#define EXPAND_ARGS__(how, N, ...) EXPAND(EXPAND_ARGS_##N(how, __VA_ARGS__))
#define EXPAND_ARGS_1(how, arg, ...) how(arg, #arg)
#define EXPAND_ARGS_2(how, arg, ...) how(arg, #arg), EXPAND(EXPAND_ARGS_1(how, __VA_ARGS__))
#define EXPAND_ARGS_3(how, arg, ...) how(arg, #arg), EXPAND(EXPAND_ARGS_2(how, __VA_ARGS__))
#define EXPAND_ARGS_4(how, arg, ...) how(arg, #arg), EXPAND(EXPAND_ARGS_3(how, __VA_ARGS__))
// ...
#define MVAR(...) Print(EXPAND_ARGS(EXPAND_NAME_VALUE, __VA_ARGS__))
#include <string>
#include <iostream>
template <typename T>
void Print(const std::string& name, T&& value)
{
std::cout << name << ": " << value << "\n";
}
template <typename T, typename... Ts>
void Print(const std::string& name, T&& value, Ts&&... other)
{
Print(name, value);
Print(std::forward<Ts>(other)...);
}
int main()
{
int heyo = 5;
float whoo = 7.5;
double eyy = 2;
std::string s = "hello";
MVAR(heyo, whoo, eyy, s);
}
Output:
heyo: 5
whoo: 7.5
eyy: 2
s: hello