5

我正在尝试在 C++ 中创建一个简单的 Signals/Slots 系统而不使用 boost,但是当我尝试将它与参数一起使用时遇到了一些问题,这是我的代码:

我的信号课:

template <typename T> 
class Signal
{
private:
    typedef std::function<T> Slot;

public:
    Signal();

    void connect( Slot slot );
    void emit( T data );
    void emit();

private:    
    std::vector<Slot> slots;    
};

我的测试课:

class Object
{
public:
    Object();
    void sayHello(  int i  );
};

所以,我像这样使用我的课程:

Signal<void(int)> signal;
signal.connect( std::bind( &Object::sayHello, player, std::placeholders::_1 ) );
signal.emit( 0 );

我在 Signal.cpp 中收到警告: 候选函数不可行:第一个参数没有从 'void (*)(int)' 到 'int' 的已知转换;

在这段代码中:

template <typename T>
void Signal<T>::emit( T data )
{
    typename std::vector<Slot>::iterator i;
    Slot t;

    for( i = this->slots.begin(); i != this->slots.end(); i++ )
    {
        t = (*i);
        t( data );   // Here
    }
}

我该如何解决?如果我想给我的“发射”方法一个对象或多个参数,我可以做吗?

谢谢!

4

1 回答 1

6

Signal从您的班级中挑选三行:

template <typename T> 
    // ...
    typedef std::function<T> Slot;
    // ...
    void emit( T data );

并声明您的信号:

Signal<void(int)> signal;

答案应该很明显:void emit(T)变成void emit(void(*)(int))(函数类型,例如void(int)当它们是函数参数时转换为指针)。

我只是建议使用每个使用的类模板都采用相同的方式T<Signature>:部分专业化。

template<class Sig>
class Signal;

template<class R, class... Args>
class Signal<R(Args...)>{
  // ...
  typedef std::function<R(Args...)> Slot;
  // ...
  void emit(Args... args) const{
    // iterate over slots and call them, passing `args...`
  }
};
于 2012-11-07T20:49:53.970 回答