尝试简化您的示例并考虑以下问题:
#include<utility>
template<typename T>
void foo(std::pair<char*, T>) {}
int main() {
foo({"a", 1});
}
它无法编译,as you can see。
问题是{ "a", 1 } 不是std::pair,即使你可以从它构造一个,如下所示:
#include<utility>
void foo(std::pair<char*, int>) {}
int main() {
foo({"a", 1});
}
错误很明显:
无法推断模板参数“T”
你为什么不能?
一旦知道T,编译器就可以构造这样的一对。无论如何,T 必须推导出来,而编译器不能这样做,因为 { "a", 1 } 不是可以推导出它的对。
无论如何,{ "a", 1 } 可以转换为一对,在特定情况下转换为std::pair<char *, T> 的特化,但首先必须推导出T。
从什么推导出来的?当然是一对,但你还没有一对。
以此类推,循环往复。
现在让我们讨论一下您尝试做一些涉及可变参数模板的类似操作:不用说,即使上面显示的更简单的示例也无法编译,它的可变参数扩展(如果有)也不会编译更多或更少的原因。
有没有办法为任意数量的参数对编写函数 foo?
我会说不,除非您使用对作为 foo 的参数。
它遵循一个最小的工作示例:
#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"));
}
如果你愿意,你也可以推导出第一个参数,只要它的类型是固定的:
#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"));
}
否则如果不固定可以这样做:
#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"));
}