Calling a base member function of a call through a member function pointer to a virtual function

I have a situation where I want a member function pointer to a virtual function to avoid dynamic dispatch. See below:

struct Base { virtual int Foo() { return -1; } }; struct Derived : public Base { virtual int Foo() { return -2; } }; int main() { Base *x = new Derived; // Dynamic dispatch goes to most derived class' implementation std::cout << x->Foo() << std::endl; // Outputs -2 // Or I can force calling of the base-class implementation: std::cout << x->Base::Foo() << std::endl; // Outputs -1 // Through a Base function pointer, I also get dynamic dispatch // (which ordinarily I would want) int (Base::*fooPtr)() = &Base::Foo; std::cout << (x->*fooPtr)() << std::endl; // Outputs -2 // Can I force the calling of the base-class implementation // through a member function pointer? // ...magic foo here...? return 0; } 

For the curious, the reason I want this is because the derived class implementation uses the utility class for memoize (add cache) to the base class implementation. The utility class takes a pointer to a function, but, of course, the function pointer dynamically sends the most derived class, and I get infinite recursion.

Is there any syntax that allows me to reproduce the behavior of static dispatching, which I can achieve with x->Base::foo() , but through a function pointer?

+5
source share
2 answers

You can force the Base* slicing as follows:

 std::cout << (static_cast<Base>(*x).*fooPtr)() << std::endl; // Outputs -1 
+1
source

There is no independent "member function pointer" with the required property. The immediate task of the associated member function is to close:

 Base * x = new Derived; auto f = [x]() { x->Base::Foo(); } f(); 

If your Base class is a special one-time use case and is under your control, you should probably add some kind of β€œaccept visitor” function to it so that you can dynamically pass dynamic member members, for example x->accept(foo_caller); etc. Example in C ++ 14:

 struct X { template <typename F> auto accept(F && f) { return [this, &f](auto &&... args) { return f(this, std::forward<decltype(args)>(args)...); }; } virtual void foo() const { std::cout << "base\n"; } }; 

Using:

 void call_static_foo(X * p) { p->accept([](X * that){that->X::foo();}); } 
0
source

All Articles