这是一个带有模板的函数模板template-parameter:
template <template <typename, typename> class TT>
TT<int, double>
make(int i, double d)
{
return TT<int, double>(i, d);
}
您指定一个具有两个类型参数的类或别名模板,此函数将使用此模板的特化,使用int 和double 作为模板参数创建。例如:
make< std::pair >(42, 4.2);
这会返回一个std::pair<int, double>。
我们现在可以“模板化”这个函数的(函数)参数:
template <template <typename, typename> class TT, typename Arg0, typename Arg1>
TT<Arg0, Arg1>
make(Arg0 a0, Arg1 a1)
{
return TT<A0, A1>(a0, a1);
}
模板参数Arg0 和Arg1 旨在从用于调用函数的(函数)参数的类型推导出来:
int i = 42;
double d = 4.2;
make< std::pair >(i, d); // returns a `std::pair<int, double>`
对于更复杂的数据类型,我们可能希望使用完美转发:
make< std::pair >( 42, std::vector<int>(1000) );
这将返回一个std::pair<int, std::vector<int>>。
make 的上述定义会将通过std::vector<int>(1000) 创建的临时向量移动 到第二个函数参数中。但是,它会从那里复制到通过TT<A0, A1>(a0, a1) 创建的对象中。
我们可以改变make的定义来实现完美转发:
template <template <typename, typename> class TT, typename Arg0, typename Arg1>
TT<Arg0, Arg1>
make(Arg0&& a0, Arg1&& a1)
{
return TT<A0, A1>(std::forward<A0>(a0), std::forward<A1>(a1));
}
通过std::vector<int>(1000) 创建的临时向量将被移动到返回语句中创建的对象中。
现在,我们可以将这个函数模板泛化为 N 个参数;模板 template-parameter 也必须被泛化,以便您可以传递任何带有一些类型参数的类或别名模板。
template <template <typename...> class TemplateClass, typename... Args>
TemplateClass<Args...> make(Args&&... args)
{
return TemplateClass<Args...>(std::forward<Args>(args)...);
}