【发布时间】:2020-09-28 08:01:15
【问题描述】:
我正在使用一个 open62541 库,它的功能几乎都是静态的。我得在open62541的函数中写一些回调函数,回调函数绑定了一些非静态函数。
所以问题是我如何制作:
A类的静态函数调用一个std::function,绑定到B类的非静态函数?
为了让问题更简单,我举个例子:
#include <iostream>
#include <functional>
using namespace std;
namespace C {
std::function<void(void)>C_foo;
}
class B
{
public:
B()
{
C::C_foo=std::bind(&B::middleMan,this);
}
std::function<void(void)>B_foo;
void middleMan()
{
B_foo();
}
static void talkTheJoke()
{
C::C_foo();
}
};
class A
{
public:
void Knock_knock()
{
std::cout<<"who's there?"<<std::endl;
}
};
int main()
{
A m_A;
B m_B;
// response "who's there?"
m_A.Knock_knock();
m_B.B_foo=std::bind(&A::Knock_knock,m_A);
//response "who's there?" again "
B::talkTheJoke();
return 0;
}
有A类和它们的非静态成员函数A::Knock_knock(),我希望B类的静态成员函数可以回调并且作用和A::Knock_knock()一样。
我在那里放了一个 B_foo 作为一个回调函数,它将绑定 A::Knock_knock()。由于 B::talkTheJoke() 是静态的,而 B_foo 不是,因此 B::talkTheJoke() 似乎无法调用 B_foo。
所以我把命名空间C作为中间人,C中的std::函数可以被静态函数B::talkTheJoke()调用,也可以绑定到非静态std::函数B:: middleMan() 可以调用 B_foo。
故事大概是这样的:
B::talkTheJoke() ----> m_B.B_foo --(std::bind)--> m_A.Knock_knock() ( X , 无效)
B::talkTheJoke() ----> C::C_foo() --(std::bind)--> m_B.middleman() ----> m_B.B_foo --(std:: bind)--> m_A.Knock_knock() ( O ,works )
但是,这个解决方案真的很丑,
这样做的正确方法是什么?
【问题讨论】:
-
你需要一个对象来调用非静态方法,无论是在另一个静态方法中还是在其他地方
-
请注意,您还可以将更复杂的类型定义为
std::vector或std::map,甚至可以将您自己的类型定义为静态。这允许在此用例中管理回调/std::function时具有更大的灵活性。但是没有解决方法:如果该函数只是通过地址(衰减)接收,您将需要一些全局存储来实现动态行为。另一种方法是,调用者为您提供传递状态的方法(通常在 c 代码中看到)。 -
为什么不将
B_foo设为静态,然后去掉整个C命名空间。我不清楚你为什么需要它。 -
为什么它首先是静态的?
标签: c++ std-function stdbind