My problem is a bit complicated. I have one class (e: Component) which have Ports objects. When a Component create a Port object, it pass one of its methods to the Port constructor.
Methods signatures :
typedef std::vector<std::string> (Component::*ComponentMethod)(std::vector<std::string>);
It works fine if I do :
// in class Component
std::vector<std::string> Component::test_method( std::vector<std::string> ) {
std::cout << "Hello !\n";
// Do stuff
}
// Port ctor : Port( ComponentMethod callback );
Port* p = new Port(&Component::test_method);
Well... now, my problem is that I make subclasses of class Component, and I don't know how to pass sublcasses methods to a Port.
// in class SubtypeComponent
std::vector<std::string> SubtypeComponent::test_method2( std::vector<std::string> ) {
std::cout << "Hello !\n";
// Do stuff
}
// Port ctor : Port( ComponentMethod callback );
Port* p = new Port(&SubtypeComponent::test_method2);
// ERROR :'(
It seems normal : I guess the compiler expects precisely Component (only) method.
--> I'm looking for a solution to "dynamically" assign methods in Ports (but I don't think this is possible)
--> Maybe another solution should be usage of templates ? (defining "template methods pointers" instead of "Component methods pointers"), but I'm not sure.
Any help would be appreciated :)
The conversions for pointer-to-member are a bit counter intuitive at first. A pointer-to-member that refers to a base member can be implicitly converted to a pointer-to-member to a derived type (contra variance), but the opposite is not true.
If you really think about it, it does make sense: if you have a pointer to a member of base, that can be applied to a derived type, since it is guaranteed to have a base subobject. On the contrary, a pointer to member that refers to derived type might be pointing to a member that was not present in the base type, and thus the conversion would not make sense.
This is the issue in your design that you must address, if you want to hold pointers-to-member referring to a base type, the pointers must refer to members present in the base (in which case the expression
&derived::memberis of typeT base::*and there is no need to convert) and they must not have been previously stored in a pointer-to-member of derived type (after storing it, the compiler cannot know if the pointer refers to a member of base or a member of derived)