Std :: bind and not a virtual call to a base class method

I want to use std::bind and make a non-virtual call to a base class function, for example: derived_obj.BaseClass::foo()


Example:

Say I have a base class A and a derived class B. A has a virtual function foo() , which is overridden by B.

 class A { public: virtual void foo() { std::cout << "Hello from A::foo()!";} } class B : public A { public: void foo() overide { std::cout << "Hello from B::foo()!";} } 

If I want to call A::foo() from an object of class B , I make a non-virtual call:

 B b_obj; b_obj.A::foo(); // prints "Hello from A::foo()!" 


Now I want to use std::bind and make a non-virtual call A::foo() from b_obj, how to do this?

I already tried casting b_obj to A and used the address &A::foo() , but no luck.

 auto f = std::bind(&A::foo, static_cast<A*>(&b_obj)); f(); // prints "Hello from B::foo()!" but it should print "Hello from A::foo()!" 
+7
c ++
source share
2 answers

You have two options. You must either make a non-virtual call to lambda, or go to the reliable old way of slicing the object (which is a copy) that you want to pass to std::bind .

 // Base method B b_obj; b_obj.A::foo(); // prints "Hello from A::foo()!" // First method auto k = [](auto b){ bA::foo(); }; k(b_obj); // Second method auto f = std::bind(&A::foo, *static_cast<A*>(&b_obj)); f(); 

All this:

 Hello from A::foo()! Hello from A::foo()! Hello from A::foo()! 

The second method works (slices), since std::bind copies its arguments. You really should prefer lambda.

+2
source share

You can wrap the call inside lambda:

 B b_obj; auto f = std::bind([&b_obj]() { b_obj.A::foo(); } ); 

But that makes little sense if you cannot use std::bind somewhere (e.g. because of std::is_bind_expression ), since you are passing the parameter of the object to lambda capture, and not for binding.

Otherwise, using a lambda or std::function without bind should be cleaner.

+1
source share

All Articles