【问题标题】:std::function and Signal/Slot systemstd::function 和 Signal/Slot 系统
【发布时间】:2012-11-07 20:41:51
【问题描述】:

我正在尝试在 C++ 中创建一个简单的信号/插槽系统而不使用 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
    }
}

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

谢谢!

【问题讨论】:

  • this 是您想要的吗?您指定T == void(int),但emit 似乎期望T == int
  • 哎呀!谢谢,确实可以更好地工作:)

标签: c++ c++11 signals signals-slots std-function


【解决方案1】:

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&lt;Signature&gt; 的类模板都采用相同的方式:部分特化。

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...`
  }
};

【讨论】:

  • emit 似乎并没有使用任何返回类型,所以也许应该假设void
  • @ildjarn:我仍在思考最好的行动方案是什么。假设void 是其中之一,但并没有太大改变我的答案。我也在考虑一个组合器参数,它可以选择传递给emit,或者组合结果值(如折叠)或将它们传递到某个地方。
  • 哦,谢谢,我在这里学到了很多东西,而且效果很好:D。我将在 C++ 中阅读更多关于带模板的变量 args 的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
  • 1970-01-01
  • 2016-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多