Reputation: 161
I'm using an open62541 library who's functions are almost all static. I have to write some callback functions in the open62541's functions, the callback functions are binding to some non-static function.
so the problem is how do I make the:
static function of class A call a std::function, which is bind to non-static function of class B ?
to make the question simpler I make the example:
#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;
}
There are class A and their non-static member function A:: Knock_knock(), I want class B's static member function can callback and also acts the same as A:: Knock_knock().
I put a B_foo there as a callback function which would bind the A:: Knock_knock(). Since the B::talkTheJoke() is static and B_foo is not, it seems that B::talkTheJoke() cannot call the B_foo.
So I put a namespace C as a middle man, the std:: function in C can be called by static function B::talkTheJoke(), it can also be bind to non-static std:: function B:: middleMan() which can call the B_foo.
The story would look like:
B::talkTheJoke() ----> m_B.B_foo --(std::bind)--> m_A.Knock_knock() ( X , not works )
B::talkTheJoke() ----> C::C_foo() --(std::bind)--> m_B.middleman() ----> m_B.B_foo --(std::bind)--> m_A.Knock_knock() ( O ,works )
However, this solution is really ugly,
what's the correct way to do so?
Upvotes: 0
Views: 278
Reputation: 870
#include <iostream>
using namespace std;
class A
{
public:
void Knock_knock() {
std::cout<<"who's there?"<<std::endl;
}
};
class B
{
public:
static void setA( A *a ) {
m_A = a;
}
static void talkTheJoke() {
if ( m_A != nullptr )
m_A->Knock_knock();
}
private:
static A *m_A;
};
A* B::m_A = nullptr;
int main()
{
A m_A;
m_A.Knock_knock();
B::setA( &m_A );
B::talkTheJoke();
return 0;
}
Upvotes: 1