hamster on wheels
hamster on wheels

Reputation: 2893

template with one explicit argument

I try to add another template argument to the factorial example of meta programming. But the following doesn't work. What is the correct way?

Code:

#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);
}

Error:

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

Upvotes: 0

Views: 1603

Answers (2)

R Sahu
R Sahu

Reputation: 206717

You can use a helper class and its specialization to do the real work.

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);
}

Additional refinement

I would recommend changing loop to allow deduction of T.

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

Then, you can use:

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

and let T be deduced as int.

Upvotes: 4

Barry
Barry

Reputation: 303780

You cannot partially specialize function templates. Full stop.

In C++17, you will be able to write:

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

until then, I would propose just taking the depth as an integral_constant argument:

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>{} );
}

Upvotes: 6

Related Questions