带有一个显式参数的模板

时间:2016-09-28 15:58:03

标签: c++ templates metaprogramming template-meta-programming

我尝试将另一个模板参数添加到元编程的阶乘示例中。但以下不起作用。什么是正确的方法?

代码:

#include <iostream>

template <typename T, int Depth>
inline void loop(T i){
    std::cout << i;
    loop<T, Depth-1>(i - 1);
}
template <typename T, int Depth>
inline void loop<T, 0>(T i){
    std::cout << i << std::endl;
}

int main(void){
    int i = 10;
    loop<int, 3>(i);
}

错误:

test4.cpp(9): error: an explicit template argument list is not allowed on this declaration
  inline void loop<T, 0>(T i){

2 个答案:

答案 0 :(得分:6)

您不能部分专门化功能模板。完全停止。

在C ++ 17中,您将能够编写:

template <typename T, int Depth>
inline void loop(T i){
    std::cout << i;
    if constexpr (Depth > 0) {
        loop<T, Depth-1>(i - 1);
    }
}
直到那时,我建议将深度作为integral_constant参数:

template <typename T>
inline void loop(T i, std::integral_constant<int, 0> ) {
    std::cout << i << std::endl;
}

template <typename T, int Depth>
inline void loop(T i, std::integral_constant<int, Depth> ){
    std::cout << i;
    loop(i - 1, std::integral_constant<int, Depth-1>{} );
}

答案 1 :(得分:4)

您可以使用辅助类及其专业化来完成实际工作。

template <typename T, int Depth> struct LoopHelper
{
   static void doit(T i)
   {
      std::cout << i;
      LoopHelper<T, Depth-1>::doit(i);
   }
};

template <typename T> struct LoopHelper<T,0>
{
   static void doit(T i)
   {
      std::cout << i;
   }
};


template <typename T, int Depth>
inline void loop(T i){
   LoopHelper<T, Depth>::doit(i);
}

其他改进

我建议更改loop以扣除T

template <int Depth, typename T>
inline void loop(T i){
   LoopHelper<T, Depth>::doit(i);
}

然后,您可以使用:

int i = 10;
loop<3>(i);

并将T推断为int