为生产者和消费者创建通用(模板)调度器



我正在尝试创建一个模板化的调度器来处理消费者的注册和生产者的数据推送。目标是:

  1. 当用户调用push(myData(时,将使用静态(singleton ish(调度器
  2. 当用户注册对T类型的数据感兴趣的回调时,他们将回调注册到T类型的调度器
  3. #1或#2可以先出现,先注册后推,或先推后注册。这就是为什么使用静态/单例调度器的原因。还要确保生产者和消费者都引用同一个调度器
  4. 我将有许多不同的消息/数据类型通过系统,因此希望创建一个通用的生产者/消费者/调度

这就是我到目前为止所拥有的。它编译良好,但回调不起作用或被触发。在试验时,名称是临时的。

main.cpp

#include "t.h"
#include <string>
#include <iostream>
/* My concrete class/data that needs to be sent out */
class A {
public:
std::string name() const {return "A";}
};
/* Consumer callback */
void callback(const A& a);
int main() {
A a;
std::function<void(const A&)> f = callback;
/* Try and register for A objects */
reg<A>(f);
/* Push the A object, should in theory call callback() but it doesnt */
push(a);
}
void callback(const A& a) {
std::cout << "I got callbacked with " << a.name() << std::endl;
}

t.h所以在这个例子中,我希望在reg((中创建一个a对象的调度器,然后在push((上使用相同的调度器来通知观察者。我有关于类型的打印语句,用于调试此问题。

// t.h
#include <iostream>
#include <functional>
#include <vector>
#include <typeinfo>
/* Generic dispatcher of type T objects */
template<typename T>
class Dispatcher {
public:
/* Users register a callback to get incoming T objects */
void Register(std::function<void(const T&)> f) {
observers_.push_back(f);
}
/* On push() notify all observers with the new data  */
void Notify(const T& t) const {
for (auto o : observers_) {
o(t);
}
}
private:
std::vector<std::function<void(const T&)>> observers_;
};
/* For creating only 1 dispatcher of type T, so push() and reg() are referring to the same object */
template<typename T>
T& Get() {
static T t_;
std::cout << "Get " << typeid(T).name() << std::endl;
return t_;
}
/* Producers push new T objects */
template<typename T>
void push(const T& t) {
std::cout << "Push " << typeid(T).name() << std::endl;
auto d = Get<Dispatcher<T>>();
d.Notify(t);
}
/* Consumers register for new T objects */
template<typename T>
void reg(std::function<void(const T& t)> f) {
auto d = Get<Dispatcher<T>>();
std::cout << "reg " << typeid(T).name() << std::endl;
d.Register(f);
}

如果有人遇到这个问题,我找到了答案。罪魁祸首:

auto d = Get<Dispatcher<T>>();

用替换两个呼叫(注册和推送(

Dispatcher<T>& d = Get<Dispatcher<T>>();

如果有人知道为什么,我想知道。我通过在private:中实现所有构造函数(move/copy(解决了这个问题,并得到了编译错误。这会导致尝试一些东西。

最新更新