std :: function и система сигналов / слотов

Я пытаюсь создать простую систему Сигналы / Слоты в C ++ без повышения, но у меня есть некоторые проблемы, когда я пытаюсь использовать ее с параметрами, вот мой код:

Мой Сигнал класс:

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 «для 1-го аргумента;

В этом коде:

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

Решение

Выбрав три строки из вашего 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...`
}
};
6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]