如何将类成员注册为队列的回调函数?

问题描述 投票:0回答:1

类成员的 最低限度的例子代码 就是下面这段。

#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <queue>
#include <thread>

// Queue from : https://stackoverflow.com/questions/2721421
template<typename T>
class Queue {
   public:
      void Push ( T x ) { theQueue.push( x ); for (auto c : theCallBacks) { c(*this); } }
      T Pop() { auto data = T{theQueue.front()}; theQueue.pop(); return data; }
      void Register( std::function<void(Queue<T>&)> ql ) { theCallBacks.push_back( ql ); }
  private:
      std::queue <T> theQueue;
      std::vector<std::function<void(Queue<T>&)>> theCallBacks;

};

void cinFct(Queue<std::string> recvQ, Queue<std::string> sendQ) {
    auto input = std::string{};
    while(true) { std::cin >> input; sendQ.Push(input); }
}

class ConsoleModule {
        Queue<std::string> sendQ; Queue<std::string> recvQ;
        std::thread cinThread; // Simulates execution on external hardware
    public:
        void recvData(Queue<std::string>& q) {
            auto recvd = q.Pop(); std::cout << "RECEIVED FROM THREAD : " << recvd << std::endl;
            // do stuff with recvd
        }
        void sendData(Queue<std::string>& q, std::string s)  { q.Push(s); }
        ConsoleModule() :sendQ{}, recvQ{}, cinThread{cinFct, sendQ, recvQ} {
            recvQ.Register(std::bind(&ConsoleModule::recvData, *this, std::placeholders::_1));
        }
};

int main(int argc, char *argv[]) {
     auto testModule = ConsoleModule{};
}

在这段代码中,我声明了一个 回调队列 我想为其注册一个 班员功能. 该 ConsoleModule 通过这些队列模拟与外部硬件的信息交换。我在编译时有一个很长的模板错误(行的 recvQ.Register(...)),可以看到 在此链接.

这是怎么回事?

c++ multithreading templates c++17 metaprogramming
1个回答
2
投票

这有什么不好。

ConsoleModule() :sendQ{}, recvQ{}  {

    recvQ.Register([this](Queue<std::string>& q) {
        recvData(q);
    });

    std::thread t([this]() {
        cinFct(recvQ, sendQ);
    });

    cinThread = std::move(t);
}
© www.soinside.com 2019 - 2024. All rights reserved.