I have the following situation, (better in code)
我有以下情况,(代码更好)
class Foo
{
private:
typedef boost::signal<void ()> Signal;
Signal signal;
public:
void Register_SignalFunction(const Signal::slot_type& slot);
void Unregister_SignalFunction(const Signal::slog_type& slot);
}
class OtherFoo
{
Foo foo;
public:
OtherFoo()
{
foo.Register_SignalFunction(&OnSignal) //I know I can't do this that is precisely my question.
}
void OnSignal(); //what to do when signal fires
}
So the question is, how i pass a 'member-function' pointer to the Register method. Also, is this ok? What I want/need, is some sort of delegate registration system, so if anynone could point my in the right direction I'll appreciate it. Thanx in advance.
所以问题是,我如何将'member-function'指针传递给Register方法。还有,这样可以吗?我想要/需要的是某种代表注册系统,所以如果没有人能指出我正确的方向,我会很感激。提前完成。
4 个解决方案
#1
3
You would typically use boost bind:
你通常会使用boost bind:
foo.Register_SignalFunction(boost::bind(&OtherFoo::OnSignal, this));
What's going on here? :-)
这里发生了什么? :-)
The connect method of the signal takes a functor. That is an object that implements the () operator. bind takes function pointers (either to free functions or member functions) and returns a functor with the right signature.
信号的连接方法需要一个仿函数。这是一个实现()运算符的对象。 bind接受函数指针(释放函数或成员函数)并返回带有正确签名的仿函数。
Also see here:
另见:
Complete example using Boost::Signals for C++ Eventing
使用Boost :: Signals for C ++ Eventing的完整示例
and here:
how boost::function and boost::bind work
boost :: function和boost :: bind如何工作
To disconnect a signal store the return value from connect into a:
要断开信号存储,将连接的返回值转换为:
boost::signals::connection
And then call the disconnect method on that.
然后调用disconnect方法。
#2
1
Typically you'll either do:
通常你会做:
void Register_SignalFunction(const boost::function<void()> &slot) {
signal += slot;
}
Or, as an inline function:
或者,作为内联函数:
template<typename T>
void Register_SignalFunction(T &slot) {
signal += slot;
}
The latter may be slightly more efficient by removing the layer of indirection boost::function
has - but only assuming boost::signal
doesn't use boost::function
internally (which it is likely to). So use whichever one you prefer, really.
后者可能通过去除间接boost :: function has的层次来稍微提高效率 - 但只是假设boost :: signal内部不使用boost :: function(很可能)。所以,请使用您喜欢的任何一个。
#3
0
I got it working after trying a lot, here's the code:
经过多次尝试后我才开始工作,这是代码:
GraphicsDeviceManager
{
private:
typedef boost::signal<void ()> DeviceLost;
DeviceLost deviceLost;
public:
Register_DeviceLostHandler(const boost::function<void ()> &handler)
{
deviceLost.connect(slot);
}
Unregister_DeviceLostHandler(const boost::function<void ()> &handler)
{
//deviceLost.disconnect(slot);
}
}
class GameBase
{
private:
GraphicsDeviceManager* graphics;
public:
GameBase()
{
graphics = new GraphicsDeviceManager();
graphics->Register_DeviceLostHandler(boost::bind(&GameBase::OnDeviceLost, this));
}
void OnDeviceLost()
{
//do some stuff
}
}
well this code works as it should be, with one exception, if I unccomment the deviceLost.disconnect(handler) statement, I receive compilation errors like: error C266 "boost::operator ==": 4 overloads have similar conversions.
以及这个代码应该如此工作,但有一个例外,如果我取消注释deviceLost.disconnect(handler)语句,我收到编译错误,如:错误C266“boost :: operator ==”:4个重载具有类似的转换。
So, why is this happening? Do you know any other way to accomplish what I'm trying?
那么,为什么会这样呢?你知道其他任何方法来完成我正在尝试的事情吗?
#4
0
In case anyone wants a full example:
如果有人想要一个完整的例子:
#include <iostream>
#include <boost/signals2/signal.hpp>
#include <boost/bind.hpp>
#include <boost/optional/optional_io.hpp>
#define registerEvent_(A) registerEvent(boost::bind(A, this, _1, _2))
struct A
{
typedef boost::signals2::signal<int (int &, int &)> EventSignal;
typedef EventSignal::slot_type SlotType;
void registerEvent(const SlotType & slot);
void triggerAll(int& a1, int& a2);
EventSignal signal_;
};
void A::registerEvent(const SlotType & slot) { signal_.connect(slot); }
void A::triggerAll(int& a1, int& a2) {std::cout << signal_(a1, a2) << "\n";}
struct B : public A
{
B();
int myFunc(int& a1, int& a2);
};
B::B() {
#ifdef WITHMACRO
registerEvent_(&B::myFunc);
#else
registerEvent(boost::bind(&B::myFunc, this, _1, _2));
#endif
}
int B::myFunc(int& a1, int& a2) { return a1 + a2 + 1; }
int main()
{
int a1 = 2;
int a2 = 3;
B b;
b.triggerAll(a1, a2);
}
#1
3
You would typically use boost bind:
你通常会使用boost bind:
foo.Register_SignalFunction(boost::bind(&OtherFoo::OnSignal, this));
What's going on here? :-)
这里发生了什么? :-)
The connect method of the signal takes a functor. That is an object that implements the () operator. bind takes function pointers (either to free functions or member functions) and returns a functor with the right signature.
信号的连接方法需要一个仿函数。这是一个实现()运算符的对象。 bind接受函数指针(释放函数或成员函数)并返回带有正确签名的仿函数。
Also see here:
另见:
Complete example using Boost::Signals for C++ Eventing
使用Boost :: Signals for C ++ Eventing的完整示例
and here:
how boost::function and boost::bind work
boost :: function和boost :: bind如何工作
To disconnect a signal store the return value from connect into a:
要断开信号存储,将连接的返回值转换为:
boost::signals::connection
And then call the disconnect method on that.
然后调用disconnect方法。
#2
1
Typically you'll either do:
通常你会做:
void Register_SignalFunction(const boost::function<void()> &slot) {
signal += slot;
}
Or, as an inline function:
或者,作为内联函数:
template<typename T>
void Register_SignalFunction(T &slot) {
signal += slot;
}
The latter may be slightly more efficient by removing the layer of indirection boost::function
has - but only assuming boost::signal
doesn't use boost::function
internally (which it is likely to). So use whichever one you prefer, really.
后者可能通过去除间接boost :: function has的层次来稍微提高效率 - 但只是假设boost :: signal内部不使用boost :: function(很可能)。所以,请使用您喜欢的任何一个。
#3
0
I got it working after trying a lot, here's the code:
经过多次尝试后我才开始工作,这是代码:
GraphicsDeviceManager
{
private:
typedef boost::signal<void ()> DeviceLost;
DeviceLost deviceLost;
public:
Register_DeviceLostHandler(const boost::function<void ()> &handler)
{
deviceLost.connect(slot);
}
Unregister_DeviceLostHandler(const boost::function<void ()> &handler)
{
//deviceLost.disconnect(slot);
}
}
class GameBase
{
private:
GraphicsDeviceManager* graphics;
public:
GameBase()
{
graphics = new GraphicsDeviceManager();
graphics->Register_DeviceLostHandler(boost::bind(&GameBase::OnDeviceLost, this));
}
void OnDeviceLost()
{
//do some stuff
}
}
well this code works as it should be, with one exception, if I unccomment the deviceLost.disconnect(handler) statement, I receive compilation errors like: error C266 "boost::operator ==": 4 overloads have similar conversions.
以及这个代码应该如此工作,但有一个例外,如果我取消注释deviceLost.disconnect(handler)语句,我收到编译错误,如:错误C266“boost :: operator ==”:4个重载具有类似的转换。
So, why is this happening? Do you know any other way to accomplish what I'm trying?
那么,为什么会这样呢?你知道其他任何方法来完成我正在尝试的事情吗?
#4
0
In case anyone wants a full example:
如果有人想要一个完整的例子:
#include <iostream>
#include <boost/signals2/signal.hpp>
#include <boost/bind.hpp>
#include <boost/optional/optional_io.hpp>
#define registerEvent_(A) registerEvent(boost::bind(A, this, _1, _2))
struct A
{
typedef boost::signals2::signal<int (int &, int &)> EventSignal;
typedef EventSignal::slot_type SlotType;
void registerEvent(const SlotType & slot);
void triggerAll(int& a1, int& a2);
EventSignal signal_;
};
void A::registerEvent(const SlotType & slot) { signal_.connect(slot); }
void A::triggerAll(int& a1, int& a2) {std::cout << signal_(a1, a2) << "\n";}
struct B : public A
{
B();
int myFunc(int& a1, int& a2);
};
B::B() {
#ifdef WITHMACRO
registerEvent_(&B::myFunc);
#else
registerEvent(boost::bind(&B::myFunc, this, _1, _2));
#endif
}
int B::myFunc(int& a1, int& a2) { return a1 + a2 + 1; }
int main()
{
int a1 = 2;
int a2 = 3;
B b;
b.triggerAll(a1, a2);
}