Template Recursion Pickle

This is a discussion on Template Recursion Pickle within the C++ Programming forums, part of the General Programming Boards category; Originally Posted by phantomotap
O_o
You have used 'T1' as part of an argument to the 'c' template in the ...

yep, and no worries about any confusion. as i continued to think about my example after i posted it, the principle started to become clear to me, as well as how woefully ambiguous the skeleton code (for lack of a better phrase) i posted was. i appreciate your help. i could have figured that out on my own with a little experimentation - my new motto should be 'code first, post second' or something. sometimes a bit of discussion really gets the gears turning tho'.

// now consider the problem source (with corrected syntax)
template <int nrows, int ld> template <int uld>
inline void cmatrix<nrows,0,ld>::mgso( cupper<0,uld> &R){}
// the default template for 'cmatrix' doesn't have a declaration for such a function
// the parameter of 'cupper<0,?> &' doesn't match the parameter 'cupper<?,?> &'
// you've attempted to define a function of an enclosing class 'cmatrix<nrows,0,ld>'
// that is an expansion of a partial specialization of a template
// this is basically the same as the forth example above

Well there's the rub I suppose. The compiler can not infer that match, even though it may make sense to the programmer, since I can pick parameters for nrows, ncols and ld (the template parameters for cmatrix) that would enable such a match, namely ncols=0.

Alll I can say is that I'd hate to have to write a C++ compiler. Moreover I can easily imagine why templated code is not very portable across differing compilers. By the way, after debugging, it does appear that my code is working as it should.

In the recursion you have to call X1.mgso(rsub) and not X1.mgso<uld,1>(rsub), or it will not pick the overloaded specialization case, which makes sense, but I have no sense as to why it picks the correct overloaded mgso to complete the specialization case and terminate the recursion. Will this code even be portable? I especially will need to port this from MS Vis. Studio to gcc on linux.

I don't know of any compiler that fully supports template methods where this will not work.

This only relies on the compiler picking the correct overload. If a compiler doesn't pick the correct overload here it probably never does.

Without having a full example I can't be sure, but you probably do not need the 'if' statement at all because you do not need it to eliminate the recursion. The general case, the one overload, always recurses down and the terminating case, the other overload, doesn't.

In the interest of... the interesting, there are a few compilers around that do have problems with template methods that will not handle this situation. You will probably never run into them because the latest versions of all the popular compilers work correctly for this example. If supporting older or simply odd compilers is important, you can increase the portability by providing an interface that makes the choice of overloads explicit through reliance on non-template functions.

Just out of curiosity, do you want to allow any 'void cmatrix<?, ?, ?>::mgso(cupper<?, ?> &)' to be called with any 'cupper<?, ?>' reference? Or should the column size match? (Should the '$' representing 'ucols' and ncols' match in 'void cmatrix<?, $, ?>::mgso(cupper<$, ?> &)'.)