std :: bind和对基类方法的非虚拟调用

时间:2016-07-21 09:25:23

标签: c++

我想使用std::bind并对基类函数进行非虚拟调用,例如:derived_obj.BaseClass::foo()


示例:

假设我有基类 A 和派生类 B A 的虚拟函数foo() 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()!";}
}

如果我想从班级 B 的对象拨打A::foo(),我会进行非虚拟通话:

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


现在我想使用std::bind并从b_obj对A::foo()进行非虚拟调用,我该怎么做?

我已经尝试将b_obj投射到 A 并使用&A::foo()的地址,但没有运气。

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()!"

2 个答案:

答案 0 :(得分:2)

这里有两种选择。你应该在 lambda 中进行非虚拟调用,或者你可以使用可靠的旧方法切割对象(这是一个副本)你要传递给{{ 1}}。

std::bind

这一切都打印出来:

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

// First method
auto k = [](auto b){ b.A::foo(); };
k(b_obj);

// Second method
auto f = std::bind(&A::foo, *static_cast<A*>(&b_obj));
f(); 

第二种方法工作(切片),因为Hello from A::foo()! Hello from A::foo()! Hello from A::foo()! 复制了它的参数。你应该非常喜欢一个lambda。

答案 1 :(得分:1)

你可以将调用包装在lambda中:

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

但这没有什么意义,除非你只能在某处使用std::bind(例如因为std::is_bind_expression),因为你将object参数传递给lambda的捕获,而不是绑定。

否则只使用lambda或std::function而不是bind应该更干净。