Is there an elegant way to specialize a template based on one of its template parameters?
Ie.
template<int N> struct Junk {
static int foo() {
// stuff
return Junk<N - 1>::foo();
}
};
// compile error: template argument '(size * 5)' involves template parameter(s)
template<int N> struct Junk<N*5> {
static int foo() {
// stuff
return N;
}
};
template<> struct Junk<0> {
static int foo() {
// stuff
return 0;
}
};
Ie. I am trying to specialize a template based on the parameter being divisible by 5. The only way I can seem to do it is like below:
template<int N> struct JunkDivisibleBy5 {
static int foo() {
// stuff
return N;
}
};
template<int N> struct Junk {
static int foo() {
// stuff
if ((N - 1) % 5 == 0 && N != 1)
return JunkDivisibleBy5<N - 1>::foo();
else
return Junk<N - 1>::foo();
}
};
template<> struct Junk<0> {
static int foo() {
// stuff
return 0;
}
};
But this is significantly less elegant, and also necessitates instantiation of all templates even if the template argument shouldn't require it.
How's this:
#include <iostream>
using namespace std;
template < typename T, T N, T D >
struct fraction {
typedef T value_type;
static const value_type num = N;
static const value_type denom = D;
static const bool is_div = (num % denom == 0);
};
template< typename T, T N, T D, bool P >
struct do_if {
static void op() { cout << N << " NOT divisible by " << D << endl; }
};
template< typename T, T N, T D >
struct do_if< T, N, D, true > {
static void op() { cout << N << " divisible by " << D << endl; }
};
template < int N >
void foo() {
typedef fraction< int, N, 5 > f;
do_if< typename f::value_type, f::num, f::denom, f::is_div >::op();
}
int main() {
foo< -5 >();
foo< -1 >();
foo< 0 >();
foo< 1 >();
foo< 5 >();
foo< 10000005 >();
return 0;
}
Using D programming language templates, one could write it as:
struct Junk(int N)
{
static int foo()
{
static if (N == 0)
return 0;
else static if ((N % 5) == 0)
return N;
else
return Junk!(N - 1).foo();
}
}
static if's are executed at compile time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With