specialize template member in derived class

3511 views c++
0

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?

answered question

Have you tried adding using A::dosomething; inside B body? When you define dosomething inside B, you hide all inherithed dosomething

1 Answer

6

This is not supported. Emphasis mine:

Member function templates

Destructors and copy constructors cannot be templates. If a template constructor is declared which could be instantiated with the type signature of a copy constructor, the implicitly-declared copy constructor is used instead.

A member function template cannot be virtual, and a member function template in a derived class cannot override a virtual member function from the base class.

Your definition of B::dosomething<>() hides the definition of A::dosomething<>().

posted this

Have an answer?

JD

Please login first before posting an answer.