pur*_*dox -1 c++ templates typedef variadic-templates perfect-forwarding
我从这个答案中看到了这段代码的片段,我似乎无法理解模板和类型名的排列如何创建main()中显示的最终函数调用.
特别是,可变参数模板模板的安排和std :: forward的使用让我很困惑.
任何人都可以打破这段代码,以便我能更好地理解它吗?
#include <utility>
template <template <typename...> class TemplateClass, typename... Args>
TemplateClass<Args...> make(Args&&... args)
{
return TemplateClass<Args...>(std::forward<Args>(args)...);
}
int main()
{
make<std::pair>(1, 2);
}
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激.
这是一个带有模板模板参数的函数模板:
template <template <typename, typename> class TT>
TT<int, double>
make(int i, double d)
{
return TT<int, double>(i, d);
}
Run Code Online (Sandbox Code Playgroud)
您指定了一个具有两个类型参数的类或别名模板,此函数将使用此模板的特化,使用int和double作为模板参数创建.例如:
make< std::pair >(42, 4.2);
Run Code Online (Sandbox Code Playgroud)
这会返回一个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);
}
Run Code Online (Sandbox Code Playgroud)
模板参数Arg0和Arg1旨在被从类型的用来调用所述功能的(函数)的参数推导出:
int i = 42;
double d = 4.2;
make< std::pair >(i, d); // returns a `std::pair<int, double>`
Run Code Online (Sandbox Code Playgroud)
对于更复杂的数据类型,我们可能希望使用完美转发:
make< std::pair >( 42, std::vector<int>(1000) );
Run Code Online (Sandbox Code Playgroud)
这会返回一个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));
}
Run Code Online (Sandbox Code Playgroud)
通过创建的临时向量std::vector<int>(1000)将移动到return语句中创建的对象中.
现在,我们可以将这个函数模板推广到N个参数; 模板template-parameter也必须进行通用化,以便您可以传递任何带有一些类型参数的类或别名模板.
template <template <typename...> class TemplateClass, typename... Args>
TemplateClass<Args...> make(Args&&... args)
{
return TemplateClass<Args...>(std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)