2012-08-10 109 views
12

我有点困惑,因为默认参数模板和可变参数模板参数都必须是模板的最后一个参数。那么我的函数的官方语法是什么?默认参数模板vs variadic模板:最后一个模板参数是什么?

template<typename T, class T2 = double, unsigned int... TDIM> myFunction(/* SOMETHING */) 

template<typename T, unsigned int... TDIM, class T2 = double> myFunction(/* SOMETHING */) 

回答

17

其实,模板参数包和默认参数不是最后一个功能,如果任何涉及将推断后(或默认):

template<class T, class... Args, class T2 = int, class T3> 
void f(T3){} 

请注意,你不能为T2指定什么,因为一切都将通过一个可变包被吞噬。最后,我想说,如果要手动指定默认参数,请将可变参数包放在默认参数后面。对于推断包装,它更像是一种风格选择,我个人会把它们放在最后。

需要注意的是,如果他们推导出另一个模板的一部分,你甚至可以有多个可变参数组:

template<class...> struct pack{}; 

template<class T, class... P1, class... P2, class T2> 
void f(pack<P1...>, pack<P2...>, T2){} 

在这样的情况下,我把相关的包装和其他模板参数到他们的功能参数,即按照相同的顺序。

对于(主要)类模板,当然这是不同的,因为不能推导出参数。事实上,可变参数包是在模板参数列表的末尾:

template<class T, class... Args, class T2=int> 
struct X{}; // error 

对于部分特例,顺序并不重要,它再次一个纯粹的风格上的选择。我个人会像之前一样将它们放在主模板的参数中。

template<class T1, class T2> 
struct X{}; 

template<template<class...> class T1, class... A1, 
    template<class...> class T2, class... A2> 
struct X<T1<A1...>, T2<A2...>>{};