2

if I declare:

class Avoidance : public Schema<std_msgs::String,prog1::Command>{

and I try to

    void*(Schema<std_msgs::String,prog1::Command>::*pt)();
    pt=&Avoidance::frontBusy;

compiler report me

error: cannot convert ‘void* (Avoidance::*)()’ 
to 
‘void* (Schema<std_msgs::String_<std::allocator<void> >, prog1::Command_<std::allocator<void> > >::*)()’ in assignment

why? Avoidance inherits from

  Schema<std_msgs::String,prog1::Command>

then Avoidance IS Schema<.....>

volperossa
  • 1,339
  • 20
  • 33
  • Your answer is given here: [why can't I cast a pointer to Derived class member function to the same but of class Base](http://stackoverflow.com/questions/10162823/why-cant-i-cast-a-pointer-to-derived-class-member-function-to-the-same-but-of-c) – Jack Aidley Jan 18 '13 at 15:19

2 Answers2

3

That's not how member function pointers work. If frontBusy is a base function, you need to type the pointer appropriately. The dispatch will still work as expected, though!

Here's a basic example:

struct A { virtual void f() = 0; };
struct B : A { virtual void f() { } };

void dispatch(void (A::*pf)(), A & a)
{            //    ^^^^^
  (a.*pf)();
}

int main()
{
  B x;
  dispatch(&A::f, x);  // calls x.B::f()
}  //      ^^^^^

So, in your case you want:

void (Schema<std_msgs::String,prog1::Command>::*p)()
                        = &Schema<std_msgs::String,prog1::Command>::frontBusy;
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
2

Getting rid of templates to simplify, suppose you have

class B {
public:
    void f();
};

class D : public B {
public:
    void g();
};

It might seem a little backwards at first, but you can cast void (B::*)() to void (D::*)(), but you cannot cast void (D::*)() to void (B::*)(). This makes sense when you think about how they would later be used.

void test() {
    void (D::*p)() = &B::f; // OK!
    void (B::*q)() = &D::g; // ERROR!

    B b;
    D d;

    (d.*p)(); // Calls B::f on `d`.  Okay, `B::f` is an inherited member.
    (b.*q)(); // Calls D::g on `b`?? But that's not a member of `b` at all!
}
aschepler
  • 70,891
  • 9
  • 107
  • 161
  • // Calls D::g on `b`?? But that's not a member of `b` at all! ok, but there is the same problem in general casting; if I cast a inerhitance class to a base class I know I can't access to member of class present that aren't declared in base class, it's a common rule; why in function pointer don't do simply the same? – volperossa Jan 18 '13 at 15:31
  • The rules I described are for implicit casts. Explicit casts are more generous and more dangerous. Just like you can implicitly cast `D*` to `B*`, but you can only convert `B*` to `D*` with an explicit cast. – aschepler Jan 18 '13 at 15:34