Starting with the following example:
#include <cstdio>
template<int X, int Y>
struct C {
template<int Z> void bar() {printf("Generic %d/%d\n",X,Y);}
void foo() {bar<Y>();}
};
int
main(int argc, char *argv[])
{
C<0,0> c0;
c0.foo();
C<0,1> c1;
c1.foo();
}
I'd like to now define additional "bar()
" functions specialized on the value of "Y
". Specifically something like the inserted lines below (sorry I don't know how to otherwise highlight them):
#include <cstdio>
template<int X, int Y>
struct C {
template<int Z> void bar() {printf("Generic %d/%d\n",X,Z);}
template<> void bar<1>() {printf("Special %d/1\n",X);}
void foo() {bar<Y>();}
};
template<int X> template<> C<X,2>::bar<2>() {printf("Special %d/2\n",X);}
int
main(int argc, char *argv[])
{
C<0,0> c0;
c0.foo();
C<0,1> c1;
c1.foo();
}
Sadly, neither of those approaches seems to be valid/compile (gcc/9.3.0, -std=c++11). ex:
tempspec.cpp:94:12: error: explicit specialization in non-namespace scope ‘struct C<X, Y>’
94 | template<> void bar<1>() {printf("Special %d/1\n",X);}
| ^
tempspec.cpp:94:26: error: template-id ‘bar<1>’ in declaration of primary template
94 | template<> void bar<1>() {printf("Special %d/1\n",X);}
| ^
tempspec.cpp:97:33: error: expected initializer before ‘<’ token
97 | template<int X> void C<X,2>::bar<2>() {printf("Special %d/2\n",X);}
| ^
I know I can't partially specialize a function (which is what I really want to do) but I thought here I was partially specializing the struct, and fully specializing the function.
So the question is, how do I define additional specifications of "bar()
" as a member function?
(As for why, say that "bar()
" is a stencil computation and "Y
" is the size of the stencil. Based on "Y
" I may have different implementations optimized for certain sizes.)