信号-槽机制的实现
#include<vector>
#include<functional>
template<class... Args>
class Signal{
std::vector<std::function<void(Args...)>> slots;
template <class T, size_t... Index>
void connectMemberFunc(T *obj, void (T::*func)(Args...), std::index_sequence<Index...>)
{
#ifdef __GNUC__
std::function<void(Args...)> f {
std::bind(func, obj, std::_Placeholder<Index + 1>{}...)
};
#elif defined _MSC_VER
std::function<void(Args...)> f {
std::bind(func, obj, std::_Ph<Index + 1>{}...)
};
#endif
this->slots.push_back(f);
}
public:
void send(Args&& ...args){
for(auto& slot:this->slots)
slot(std::forward<Args>(args)...);
}
template<class Callable>
void connect(Callable slot){
this->slots.push_back(slot);
}
void connect(void(*slot)(Args...)) {
this->slots.push_back(slot);
}
template <class T>
void connect(T* obj, void (T::* slot)(Args...)) {
this->connectMemberFunc(obj, slot, std::index_sequence_for<Args...>());
}
};
// 无参特化
template<>
class Signal<void> {
std::vector<std::function<void(void)>> slots;
public:
void send() {
for (auto& slot : this->slots)
slot();
}
template<class Callable>
void connect(Callable slot) {
this->slots.push_back(slot);
}
void connect(void(*slot)(void)) {
this->slots.push_back(slot);
}
template <class T>
void connect(T* obj, void (T::* slot)(void)) {
this->slots.push_back(std::bind(slot, obj));
}
};
测试实现
#include<iostream>
struct A {
void operator()() {
std::cout << "No Args Callable Object" << std::endl;
}
void operator()(int a) {
std::cout << "Args Callable Object:" << a << std::endl;
}
void func() {
std::cout << "No Args Member Function" << std::endl;
}
void func(int a) {
std::cout << "Args Member Function:" << a << std::endl;
}
};
void func() {
std::cout << "No Args Function" << std::endl;
}
void func(int a) {
std::cout << "Args Function:" << a << std::endl;
}
int main() {
// 定义信号
Signal<void> s1;
Signal<int> s2;
A a;
// 连接槽
s1.connect(func);
s1.connect(&a, &A::func);
s1.connect(a);
s2.connect(func);
s2.connect(&a, &A::func);
s2.connect(a);
// 发出信号
s1.send();
s2.send(5);
return 0;
}