微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为生产者和消费者创建通用模板调度程序

如何解决为生产者和消费者创建通用模板调度程序

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

  1. 用户调用 push(myData) 时,将使用静态(单例)调度程序。
  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>>();

替换两个调用(reg和push)
Dispatcher<T>& d = Get<Dispatcher<T>>();

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。