Reputation: 2893
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
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
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