Reputation: 2200
I want to make a pipeline, where I'd specify a few processing classes as template arguments and the template would pass data between them etc.
So I've kinda got it working with VC/IntelC, but not clang/gcc. How do I fix this code and make it portable?
Here you can see that microsoft compilers understand it: https://godbolt.org/g/0UBnTU
But with gcc/clang I'm getting "explicit specialization in non-namespace scope", or "function template partial specialization is not allowed" if I try a different approach.
#include <stdio.h>
struct proc1 { int x[1]; };
struct proc2 { int x[2]; };
struct proc3 { int x[3]; };
struct proc4 { int x[4]; };
template< int N > struct S1;
template<> struct S1<0> { typedef proc1 t; };
template<> struct S1<1> { typedef proc2 t; };
template<> struct S1<2> { typedef proc3 t; };
template<> struct S1<3> { typedef proc4 t; };
template< int _N, template<int i> class Sx >
struct S2 {
enum{ N=_N };
void* tbl[N];
template< typename TT > struct print {
template< typename Self >
static void x( Self* This, int ii ) {
This->tbl[ii] = new TT;
printf( "sizeof(Sx<%i>)=%i sizeof(Self)=%i\n", ii, int(sizeof(TT)), int(sizeof(Self)) );
}
};
template< class Self, template<typename TT> class func >
struct for_all {
template< int ii > static void x( Self* This ) {
func< typename Sx<ii>::t >::x(This,ii);
x<ii+1>(This);
}
template<> static void x<N>( Self* This ) {}
};
void test( void ) {
printf( "N=%i\n", N );
for_all<S2,print>::x<0>(this);
}
};
S2<4,S1> X;
int main( ) {
X.test();
}
Upvotes: 0
Views: 68
Reputation: 4715
The reason your code is invalid is because there are no function template specialization in C++, therefore the template <> static void x<N>(Self* This){}
is invalid.
What you can do is overloading:
template <int I>
struct integer_constant {};
template <int I>
void foo(integer_constant<I>)
{
std::cout << I << '\n';
foo(integer_constant<I - 1>());
}
void foo(integer_constant<0>)
{
std::cout << 0 << '\n';
}
int main()
{
foo(integer_constant<5>());
}
In your case, it looks like this:
template< class Self, template<typename TT> class func >
struct for_all {
template< int ii > static void x( Self* This, integer_constant<ii> ) {
func< typename Sx<ii>::t >::x(This,ii);
x(This, integer_constant<ii + 1>());
}
static void x( Self* This, integer_constant<N> ) {}
};
I've rolled my own integer_constant
for this example since you can't have C++11, but if you can, you should use something standard like std::integral_constant
Upvotes: 1