I have a base class with a template member, which is explicitly specialized for some cases. A derived class further specializes the template member of the base class. The rationale beyond that is that the various specialization of the template member do "logically" the same job, adapting to a specific situation. The base class provides some template specializations, which do the task for some cases, a derived class should "extend" the same task to other cases, by further specializing the template member.
Here is a minimal example to illustrate the problems I encounter.
#include <iostream>
struct A {
template <int i>
void dosomething();
void show();
};
template<>
void A::dosomething<0>()
{
std::cout << "0 in A" << std::endl;
}
void A::show()
{
dosomething<0>();
}
struct B : A {
// Without the following declaration:
// error: template-id ‘dosomething<1>’ for ‘void B::dosomething()’
// does not match any template declaration
template <int i>
void dosomething();
};
template<>
void B::dosomething<1>()
{
std::cout << "1 in B" << std::endl;
}
int main()
{
A x;
x.dosomething<0>();
B y;
y.dosomething<0>(); // Link error!
y.show();
y.dosomething<1>();
return 0;
}
The template member A::dosomething()
is explicitly specialized for i=0
in the base class. The code for the template is explicitly generated, and called in the member A::show()
.
The first problem I found are:
A) Without a duplicated declaration
template <int i>
void dosomething();
inside the definition of B
, the code does not compile, with the error:
template-id ‘dosomething<1>’ for ‘void B::dosomething()’
does not match any template declaration.
Why is the previous declaration in the base class A
not visible?
B) The code above gives rise to a link error:
undefined reference to `void B::dosomething<0>()'
The error is due to the call y.dosomething<0>()
in main. It can be avoided by calling instead y.A::dosomething<0>()
. Why is dosomething<0>()
apparently invisible in an instance of B
?