# mem_fun with inheritance

## Recommended Posts

I'm trying to convert a void ()(void) member function for a derived class to a functor which takes a base class pointer as its parameter. I figured this should be possible since the derived member function is really void ()(Derived *). I'm expecting it to be convertable to a functor of void ()(Base *), following the usual implicit upcast rules. However, the compiler is giving me an invalid conversion from Base* to Derived*. I'm assuming this downcast is the result of some sort of mem_fun template magic.
#include <iostream>
#include <tr1/functional>

struct A
{
typedef std::tr1::function<void (A *)> F;

explicit A(const F &f) : f(f) {}

void Do()
{
f(this);
}

private:
F f;
};

struct B : A
{
B() : A(std::mem_fun(&B::MyF)) {}

private:
void MyF()
{
std::cout << "check" << std::endl;
}
};

int main()
{
B().Do();
return 0;
}


Any ideas how I can make this work?

##### Share on other sites
Quote:
 Original post by dcosbornI figured this should be possible since the derived member function is really void ()(Derived *). I'm expecting it to be convertable to a functor of void ()(Base *), following the usual implicit upcast rules.

Wrong, the subtyping lattice is reversed for function arguments. That is, a function that accepts Derived* does not accept all Base* arguments (what about Base objects that are not Derived?). Your conversion is simply incorrect.

##### Share on other sites
Yeah, I see what you mean. It should be possible with a static_cast though right? Something like this?
static_cast<std::mem_fun_t<void, A> &>(std::mem_fun(&B::MyF))
I found a much cleaner solution: use a pure virtual F and derive it. Pretty obvious, but I was coding this at 4am so, you know... [rolleyes]

##### Share on other sites
Quote:
 Original post by dcosbornYeah, I see what you mean. It should be possible with a static_cast though right? Something like this?

No, it will never be possible. Your cast can be mathematically proven to be incorrect. You can get around the compiler's common sense warnings with a reinterpret_cast, but don't expect to get any kind of correct behaviour out of it.

##### Share on other sites
Also, to be pedantic, the types for the member functions are void(Derived::*)() (and similarly for Base), not void()(Derived*) - the latter is not a type, although void(*)(Derived) would be a free function accepting a Derived object by value :) (I'd like to justify that by saying that it'd be important when searching for help, but it seems that Google ignores punctuation :( )

## Create an account

Register a new account

• ## Partner Spotlight

• ### Forum Statistics

• Total Topics
627684
• Total Posts
2978627

• 9
• 14
• 12
• 10
• 12