For some reason with gcc 4.3 I can not solve the problem of explicit template member function instantiation. C++ restrictions and some compiler quirks have thwarted my efforts.
Here is my code snippet,
Code:
/* dummy class for function template recursion */
template<int n>
class ordn {
public:
ordn<n-1> sub1()
{
ordn<n-1> o1 ;
return(o1) ;
}
ordn<n+1> add1()
{
ordn<n+1> o1 ;
return(o1) ;
}
} ;
template<int nrows, int ld>
class cupper {
/* lots of code */
/* urows template variable is a kludge since in fact urows = nrows in all cases */
template <int urows, typename T >
inline void invrec(T &on)
{
cupper<urows-1,ld> rsub(subptr()) ;
/* some code */
// rsub.invrec<urows-1>(o1) ;
/* Error occurs on next line. gcc can't insantiate it even though all parameters
are completely specified and in fact are template variables! */
rsub.invrec<urows-1, ordn<urows-1> >(on.sub1()) ; /* recursive inversion of submatrix */
}
/* trick to obtain full function member specialization of a templated member
function */
template<int urows>
void invrec(ordn<1> &o1)
{
cuComplex dd = this->getval(0,0) ;
float c[2] ;
c[0] = ((float) 1.0)/dd.x;
c[1] = 0.0 ;
this->setval(c,0,0) ;
}
/* wrapper function to invoke the recursion */
void inv()
{
ordn<nrows> on ;
invrec<nrows, ordn<nrows> >(on) ;
}
} ; // end cupper
Later I instantiate cupper of size <4,4> . Unfortunately I get an error from gcc of the form:
error: no matching function for call to ‘cudamat::cupper<3, 4>::invrec(ordn<3>)’
There are a number of C++ restrictions that conspire to make this difficult. The first problem is that we are forbidden to explicitly instantiate all template parameters inside the class for a class member. (Though supposedly you can do this for an inner class if it's enclosed in a local namespace).
The second is that if you try to pull the definition out of the class definition, you run into the problem that partial specialization of function templates are not allowed. I'd have to specialize the entire class! (which is too large and complicated to consider).
Any ideas or workarounds for this?