Okay, sample code first; this is my attempt at communicating what it is that I'm trying to do, although it doesn't compile:
#include <iostream>
template <class T>
class Base
{
public:
virtual void my_callback() = 0;
};
class Derived1
: public Base<int>
, public Base<float>
{
public:
void my_callback<int>()
{
cout << "Int callback for Derived1.\n";
}
void my_callback<float>()
{
cout << "Float callback for Derived\n";
}
};
class Derived2
: public Base<int>
, public Base<float>
{
public:
void my_callback<int>()
{
cout << "Int callback for Derived2.\n";
}
void my_callback<float>()
{
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();
}
//Desired output:
// Int callback for Derived1.
// Float callback for Derived1
// Int callback for Derived2.
// Float callback for Derived2
system("Pause");
}
So, what I'm trying to do is to make a sort of wrapper class to inherit from that will automatically connect the derived class to various callback lists; it needs to connect a specific instance of the derived class to the list, and I want the "user" to have / get to make the callback functions as part of making the derived class, as you can see.
It seems like this should be able to work, although I may need to use a different syntax. If it can't work, do you have any suggestions?
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()".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With