Overriding multiple inherited templated functions with specialized versions

守給你的承諾、 提交于 2019-12-04 08:59:23

Yes, you can make this work:

#include <iostream>
using namespace std;

template <class T>
class Base
{
public:
  virtual void my_callback() = 0;
};

class Derived1 : public Base<int>, public Base<float>
{
public:
  void Base<int>::my_callback() {
    cout << "Int callback for Derived1.\n";
  }
  void Base<float>::my_callback() {
    cout << "Float callback for Derived\n";
  }
};

class Derived2 : public Base<int>, public Base<float>
{
public:
  void Base<int>::my_callback() {
    cout << "Int callback for Derived2.\n";
  }
  void Base<float>::my_callback() {
    cout << "Float callback for Derived2\n";
  }
};

int main()
{
  {
    Derived1 d;
    Base<int> * i_p = &d;
    Base<float> * i_f = &d;
    i_p->my_callback();
    i_f->my_callback();
  }
  {
    Derived2 d;
    Base<int> * i_p = &d;
    Base<float> * i_f = &d;
    i_p->my_callback();
    i_f->my_callback();
  }
}

Output:

Int callback for Derived1.
Float callback for Derived
Int callback for Derived2.
Float callback for Derived2

What you want is not possible.

You could add template specializations, though I do not know if this really helps:

template <class T>
class Base {
public:
  virtual void my_callback() = 0;
};

template <>
class Base<int> {
public:
  virtual void my_callback() {
    cout << "Base<int>::my_callback()\n";
  }
};

template <>
class Base<float> {
public:
  virtual void my_callback() {
    cout << "Base<float>::my_callback()\n";
  }
};

class Derived1 : public Base<int>, public Base<float> {
public:
  // NOTE: no my_callback() implementation here
};

class Derived2 : public Base<int>, public Base<float> {
public:
  virtual void my_callback() {
    cout << "Derived2::my_callback()\n";
  }
};


int main()
{
  {
    Derived1 d;
    Base<int> * i_p = &d;
    Base<float> * i_f = &d;
    i_p->my_callback();
    i_f->my_callback();
  }
  {
    Derived2 d;
    Base<int> * i_p = &d;
    Base<float> * i_f = &d;
    i_p->my_callback();
    i_f->my_callback();
  }
}

Output:

Base<int>::my_callback()
Base<float>::my_callback()
Derived2::my_callback()
Derived2::my_callback()

Let me try to explain why:

Derived1 d;
Base<int> * i_p = &d;
Base<float> * i_f = &d;

// will check the vtable, and will call
//  either Derived1::my_callback
//  OR Base<int>::my_callback
i_p->my_callback();

// will check the vtable, and will call
//  either Derived1::my_callback
//  OR Base<float>::my_callback
i_f->my_callback();

Though through the vtable there are two versions of my_callback() in class Derived1, you CAN NOT override either of them, you can only override both at once (like Derived2 does in the example)!

You should just provide two methods "my_callback1()" and "my_callback2()".

Massood Khaari

Whether using a template class or a non-template one, this can be done by using helper classes in this style or this one.

(It seems this is the only portable solution if you do not plan to use Microsoft specific qualified names.)

Doesn't virtuality associated with template raises an alarm in your head ? ;)

You have to choose your side, either the static, or the dynamic one.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!