Try to simplify a bit your example and consider this:
#include<utility>
template<typename T>
void foo(std::pair<char*, T>) {}
int main() {
foo({"a", 1});
}
It doesn't compile, as you can see.
The problem is that { "a", 1 }
is not a std::pair
, even if you can construct one from it as it follows:
#include<utility>
void foo(std::pair<char*, int>) {}
int main() {
foo({"a", 1});
}
The error is quite clear:
couldn't infer template argument 'T'
Why can't you?
Te compiler could construct such a pair once T
is known. Anyway, T
must be deduced and the compiler cannot do that because { "a", 1 }
is not a pair from which it can be deduced.
Anyway, { "a", 1 }
can be converted to a pair, in the specific case to a specialization of std::pair<char *, T>
, but first of all T
must be deduced.
Deduced from what? A pair, of course, but you don't have a pair yet.
And so on, in a loop.
Let's discuss now your attempt to do something similar that involves a variadic template: it goes without saying that, if even the simpler example shown above doesn't compile, its variadic extension (if any) would not compile as well for more or less the same reason.
Is there a way to write function foo for arbitrary number of argument pairs?
I would say no, unless you use pairs as arguments for foo
.
It follows a minimal, working example:
#include<utility>
template <typename... Args>
void foo(std::pair<const char*, Args>&&...) {}
int main() {
foo(std::make_pair("a", 1), std::make_pair("b", "value"));
}
If you prefer, you can also deduce the first argument, as long as its type is fixed:
#include<utility>
template <typename T, typename... Args>
void foo(std::pair<T, Args>&&...) {}
int main() {
foo(std::make_pair("a", 1), std::make_pair("b", "value"));
}
Otherwise you can do this if it's not fixed:
#include<utility>
template <typename... First, typename... Second>
void foo(std::pair<First, Second>&&...) {}
int main() {
foo(std::make_pair("a", 1), std::make_pair(0, "value"));
}