I'm trying to get a parameter pack from the list of arguments passed to a macro.
template<std::size_t N, class T, class... Ts>
constexpr bool myFunctionHelper(const char (&fmt)[N], std::size_t n);
template <std::size_t N, typename... Ts>
constexpr bool myFunction(const char (&fmt)[N]) {
return myFunctionHelper<N, Ts...>(fmt, 0);
}
#define FNC(fmt, ...) \
do { \
static_assert(myFunction<sizeof(fmt), decltype...(__VA_ARGS__)>(fmt), \
"Incorrect arg types"); \
} while (false)
But decltype doesn't work as above (sizeof does though). Is there some method to get the parameter pack?
It works if I pass the args to the myFunction and let compiler deduce the template type, but I can't pass the args further. args need not be constexpr.
Edit:
decltype(arg)
gives us the type of arg for any object. Here I'm trying to get the type info of multiple arguments as a parameter pack. If I use decltype(__VA_ARGS__)
, the build succeeds but it just gives me the type of the last param in the __VA_ARGS__
. For eg:
decltype(1, "test", 4.0)
would translate to just float
.
There doesn't exists anything like decltype...(args)
(sizeof...(__VA_ARGS__)
does though).
FNC would be used as follows
FNC("%d, %s, %0.2f\n", 1, "test", 4.0);
CodePudding user response:
Something along these lines, perhaps (not tested):
template <std::size_t N, typename Tuple, size_t... Is>
constexpr bool myFunction1(const char (&fmt)[N], std::index_sequence<Is...>) {
return myFunction<N, std::tuple_element_t<Is, Tuple>...>(fmt);
}
template <std::size_t N, typename Tuple>
constexpr bool myFunction2(const char (&fmt)[N]) {
return myFunction1<N, Tuple>(fmt, std::make_index_sequence<std::tuple_size_v<Tuple>>{});
}
The macro would do
myFunction2<sizeof(fmt), decltype(std::make_tuple(__VA_ARGS__))>(fmt)