在C 中实现信号模板
Implementing Signal template in C++
我正在尝试在C 中实现Signal
模板。
这是我到目前为止所拥有的:
Main.cpp
:
//Developed by Trofimov Yaroslav on 02.04.18
#include <iostream>
#include "Signal.h"
void f1() {
std::cout << "here in f1" << std::endl;
}
void f2() {
std::cout << "F2 F2 F2" << std::endl;
}
typedef void (* VoidResultDelegate)();
int main(void) {
Signal<VoidResultDelegate> signalVoid;
signalVoid.addListener(f1);
signalVoid.addListener(f1);
signalVoid.invoke();
signalVoid.removeListener(f2);
signalVoid.invoke();
return 0;
}
Signal.h
:
//Developed by Trofimov Yaroslav on 02.04.18
#ifndef _SIGNAL_H_TROFIMOV_
#define _SIGNAL_H_TROFIMOV_
#include "LinkedList.h"
template<typename FunctionType>
class Signal {
LinkedList<FunctionType> _delegates;
public:
Signal<FunctionType>(void)
: _delegates(LinkedList<FunctionType>()) {
}
~Signal<FunctionType>(void) {
}
void addListener(const FunctionType& delegated) {
_delegates.add(delegated);
}
void removeListener(const FunctionType& delegated) {
_delegates.remove(delegated);
}
void invoke() {
_delegates.startIteration();
while(_delegates.hasNext()) {
_delegates.next()();
}
}
};
#endif
LinkedList.h
:
//Developed by Trofimov Yaroslav on 30.03.2018
#ifndef _LINKED_LIST_H_TROFIMOV_
#define _LINKED_LIST_H_TROFIMOV_
#include <string>
#include <iostream>
#include <typeinfo>
template<typename T>
class LinkedList {
template<typename T>
struct Node {
T _data;
Node* _next;
Node()
: _next(0){}
~Node<T>() {
if(_next) {
delete _next; _next = 0;
}
}
};
Node<T>* _head;
Node<T>* _tail;
Node<T>* _iterator;
public:
LinkedList<T>()
: _head(0), _tail(0), _iterator(0) {
};
~LinkedList<T>() {
delete _head; _head = 0;
}
void add(const T& element) {
if(!_head) {
_head = new Node<T>;
_head->_data = element;
_tail = _head;
return;
}
Node<T>* newNode = new Node<T>;
newNode->_data = element;
_tail->_next = newNode;
_tail = newNode;
return;
}
void remove(const T& element) {
if(!_head) {
return;
}
if(_head->_data == element) {
_head = _head->_next;
return;
}
Node<T>* previous = _head;
Node<T>* current = _head->_next;
while(current) {
if(current->_data == element) {
previous->_next = current->_next;
return;
}
previous = current;
current = current->_next;
}
}
void startIteration() {
_iterator = _head;
}
bool hasNext() {
return (_iterator)?true:false;
}
T& next() {
T& res = _iterator->_data;
_iterator = _iterator->_next;
return res;
}
};
#endif
因此,我想添加的是传递参数的通用方法。假设现在,我有typedef void (* VoidResultDelegate)(int i);
而不是typedef void (* VoidResultDelegate)();
,这意味着我希望int
参数以某种方式出现在Signal::invoke
方法参数列表中,并在此处通过 _delegates.next()();
this _delegates.next()(i);
或类似的东西。
在C ?
中根本可以使用我正在考虑的是将另一个typename
参数传递给Signal
,该参数表示Signal::invoke
接受的参数类型,并将 _delegates.next()();
中链接列表中的元素传递给元素。但是,这种方法的问题无法控制参数的数量(这只是一个参数(。而且没有人(我的意思是一个编译器当然(强迫我将正确的参数作为typename
传递给Signal
模板。在上面的示例中,我本可以通过bool
typename
而不是int
,没有人会注意到它直到错误。
这是答案版本之后的更新:
Main.cpp
:
//Developed by Trofimov Yaroslav on 02.04.18
#include <iostream>
#include "Signal.h"
void f1(int i) {
std::cout << "here in f1" << std::endl;
}
void f2(int i) {
std::cout << "F2 F2 F2" << std::endl;
}
typedef void (* VoidResultDelegate)(int i);
int main(void) {
Signal<VoidResultDelegate, int> signalVoid;
signalVoid.addListener(f1);
signalVoid.addListener(f2);
signalVoid.invoke(-1);
signalVoid.removeListener(f1);
signalVoid.invoke(-1);
return 0;
}
Signal.h
:
//Developed by Trofimov Yaroslav on 02.04.18
#ifndef _SIGNAL_H_TROFIMOV_
#define _SIGNAL_H_TROFIMOV_
#include "LinkedList.h"
template<typename FunctionType, typename... Args>
class Signal {
LinkedList<FunctionType> _delegates;
public:
Signal<FunctionType, parameter>(void)
: _delegates(LinkedList<FunctionType>()) {
}
~Signal<FunctionType, parameter>(void) {
}
void addListener(const FunctionType& delegated) {
_delegates.add(delegated);
}
void removeListener(const FunctionType& delegated) {
_delegates.remove(delegated);
}
void invoke(Args&& ... args) {
_delegates.startIteration();
while(_delegates.hasNext()) {
(_delegates.next())(std::forward<Args>(args)...);
}
}
};
#endif
LinkedList.h
:
//Developed by Trofimov Yaroslav on 30.03.2018
#ifndef _LINKED_LIST_H_TROFIMOV_
#define _LINKED_LIST_H_TROFIMOV_
#include <string>
#include <iostream>
#include <typeinfo>
template<typename T>
class LinkedList {
template<typename T>
struct Node {
T _data;
Node* _next;
Node()
: _next(0){}
~Node<T>() {
if(_next) {
delete _next; _next = 0;
}
}
};
Node<T>* _head, _tail, _iterator;
public:
LinkedList<T>()
: _head(0), _tail(0), _iterator(0) {
};
~LinkedList<T>() {
delete _head; _head = 0;
}
void add(const T& element) {
if(!_head) {
_head = new Node<T>;
_head->_data = element;
_tail = _head;
return;
}
Node<T>* newNode = new Node<T>;
newNode->_data = element;
_tail->_next = newNode;
_tail = newNode;
return;
}
void remove(const T& element) {
if(!_head) {
return;
}
if(_head->_data == element) {
_head = _head->_next;
return;
}
Node<T>* previous = _head;
Node<T>* current = _head->_next;
while(current) {
if(current->_data == element) {
previous->_next = current->_next;
return;
}
previous = current;
current = current->_next;
}
}
void startIteration() {
_iterator = _head;
}
bool hasNext() {
return (_iterator)?true:false;
}
T& next() {
T& res = _iterator->_data;
_iterator = _iterator->_next;
return res;
}
};
#endif
您可以为Signal
类做出部分专业化,以在单独的模板参数中获取返回类型和参数。
// Declare the template without any definition
template<typename FunctionType>
class Signal;
// Add partial specialization
template<typename ReturnType, typename... Args>
class Signal<ReturnType(*)(Args...)> {
// Now you have access to return type and arguments
// Other things...
void invoke(Args... args) {
_delegates.startIteration();
while(_delegates.hasNext()) {
_delegates.next()(args...);
}
}
}
我从invoke
功能中省略了完美的转发,以使其简单。它看起来像这样。
void invoke(Args&&... args) {
_delegates.startIteration();
while(_delegates.hasNext()) {
_delegates.next()(std::forward<Args>(args)...);
}
}
相关文章:
- 在C 中实现信号模板
- 使用 Qt5 的新信号/插槽实现向滑块发出信号
- 在使用 pthread 和信号量实现生产者-消费者问题时需要帮助
- 实现信号量
- 如何用异步库实现忙信号
- 想要实现将功能类型作为参数的信号模板之类的启动
- 实现信号量时混淆了核心转储
- 使用互斥锁和信号量实现屏障
- 如何在多核系统上实现信号量
- Qt:LNK2001和LNK2019 跨源文件实现信号/时隙后会出现错误
- 使用 Qt 信号和插槽实现 c++ 回调
- 用C++实现一个二进制信号量类
- 使用x86程序集的信号量实现
- c++定时器实现-将一个成员函数分配给信号回调函数指针
- C ++自己实现信号量
- 是否存在具有基本反射的轻量级信号槽实现
- Qt:如何为所有小部件和小部件类型实现通用基类信号/插槽功能(通过虚拟基类插槽)
- 我能否仅使用事件、互斥体和信号量实现公平"wait on multiple events"?
- 创建一个类的多个实现,一个用于发送Qt信号,另一个用于直接使用硬件
- 当实现mouseDoubleClickEvent时,不会发出itemdoubleclick信号