繁体   English   中英

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

[英]std::bind and non-virtual call to base class method

我想使用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_objA并使用&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()!"

你有两个选择。 您应该在lambda中执行非虚拟调用,或者您可以使用可靠的旧方法来切换要传递给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()!

第二种方法起作用(切片),因为std::bind复制了它的参数。 你应该更喜欢 lambda。

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

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

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

否则只使用没有bind的lambda或std::function应该更干净。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM