The only way I found is to use a macro with variadic arguments to prepend std::pair
in each argument. Thanks to the recursive FOR_EACH macro, you can do something like:
template <typename... Args>
void foo(std::pair<int, Args>&&... args) {
(fooSinglePair(std::forward<std::pair<int, Args>>(args)), ...);
}
#define PARENS ()
#define EXPAND(...) EXPAND4(EXPAND4(EXPAND4(EXPAND4(__VA_ARGS__))))
#define EXPAND4(...) EXPAND3(EXPAND3(EXPAND3(EXPAND3(__VA_ARGS__))))
#define EXPAND3(...) EXPAND2(EXPAND2(EXPAND2(EXPAND2(__VA_ARGS__))))
#define EXPAND2(...) EXPAND1(EXPAND1(EXPAND1(EXPAND1(__VA_ARGS__))))
#define EXPAND1(...) __VA_ARGS__
#define FOR_EACH(macro, ...) \
__VA_OPT__(EXPAND(FOR_EACH_HELPER(macro, __VA_ARGS__)))
#define FOR_EACH_HELPER(macro, a1, ...) \
macro a1 __VA_OPT__(, FOR_EACH_AGAIN PARENS(macro, __VA_ARGS__))
#define FOR_EACH_AGAIN() FOR_EACH_HELPER
#define foo(...) foo(FOR_EACH(std::pair, __VA_ARGS__))
foo((1, 1), (2, 2.2), (3, "3"));