使用生产者-使用者模式,我想通过传递函数对象的名称(类似于A )以及这些函数在类似队列的缓冲区queue_in中获取的参数列表来提交对struct func_2()的成员函数的调用。然后,我想收集这些结果(这里是所有可能的返回类型的std::variant (double和int)),在另一个缓冲区queue_out中进行后续处理。
目前,我只能通过让q_in持有std::string并手动枚举所有可能性来破解自己的方式。当然,我也没有将任何可能的参数传递给func_1()和func_2()。
#include <iostream>
#include "blockingconcurrentqueue.h" // https://github.com/cameron314/concurrentqueue
#include <variant>using Result = std::variant<double, int>;
using queue_in = moodycamel::BlockingConcurrentQueue<std::string>;
using queue_out = moodycamel::BlockingConcurrentQueue<Result>;struct A {
explicit A(queue_in &q_in, queue_out &q_out) {
std::thread t([&]() {
for (;;) {
std::string s;
if (q_in.wait_dequeue_timed(s, -1)) {
if (s == "1")
q_out.enqueue(this->func_1());
else if (s == "2")
q_out.enqueue(this->func_2());
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
t.join();
}
double func_1() const { // func_1 might have arguments!
std::cout << "func_1() called.\n";
return 13.0f;
}
int func_2() const { // func_2 might have arguments!
std::cout << "func_2() called.\n";
return 1;
}
};void producer(queue_in &q_in, const size_t N) {
for (size_t i = 0; i != N; ++i) {
q_in.enqueue("1" /*..., arguments for func_1*/); // prefer to call the function-object instead
q_in.enqueue("2" /*..., arguments for func_2*/);
}
}
void result_consumer(queue_out &q_out) {
for (;;) {
Result r;
if (q_out.wait_dequeue_timed(r, -1)) {
std::visit([](auto &&arg) {
std::cout << "The result is: " << arg << std::endl;
}, r);
}
std::this_thread::sleep_for(std::chrono::seconds(0));
}
}
int main() {
const size_t N = 2;
queue_in q_in;
queue_out q_out;
std::thread producer_thread(producer, std::ref(q_in), N);
std::thread result_consumer_thread(result_consumer, std::ref(q_out));
A a(q_in, q_out);
producer_thread.join();
result_consumer_thread.join();
}我如何通过函数对象来代替它呢?第二,如何为A的成员函数调用任何可能的参数。第三,我是否可以避免使用类似于std::variant的结果类型?
发布于 2022-09-08 09:51:17
从@n.1.8e9-我的股份在哪里获得灵感。这里的注释是我如何使用std::function和std::bind实现上述工作的
using Result = std::variant<double, int>;
using FO = std::function<Result(void)>;
using queue_in = moodycamel::BlockingConcurrentQueue<FO>;
using queue_out = moodycamel::BlockingConcurrentQueue<Result>;struct A {
explicit A(queue_in &q_in, queue_out &q_out) {
std::thread t([&]() {
for (;;) {
FO o;
if (q_in.wait_dequeue_timed(o, -1)) {
q_out.enqueue(o());
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
});
t.detach();
}
void consumer() {
}
double func_1(double x, const size_t &s) const { // note the arguments
std::cout << "func_1() called.\n";
return x + s;
}
int func_2(int x) const {
std::cout << "func_2() called.\n";
return x;
}
};void producer(const A& a, queue_in &q_in, const size_t N) { // note the first argument: the producer() must know about some instance of A
for (size_t i = 0; i != N; ++i) {
FO o;
if (i % 2 == 0)
o = std::bind(&A::func_1, a, double(i), size_t(10));
else
o = std::bind(&A::func_2, a, int(i));
q_in.enqueue(o);
}
}
void result_consumer(queue_out &q_out) {
for (;;) {
Result r;
if (q_out.wait_dequeue_timed(r, -1)) {
std::visit([&](auto &&arg) {
std::cout << "The result is: " << arg << std::endl;
}, r);
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}int main() {
const size_t N = 2;
queue_in q_in;
queue_out q_out;
A a(q_in, q_out);
std::thread producer_thread(producer, std::ref(a), std::ref(q_in), N);
std::thread result_consumer_thread(result_consumer, std::ref(q_out));
producer_thread.join();
result_consumer_thread.join();
}输出:
func_1() called.
The result is: 10
func_2() called.
The result is: 1https://stackoverflow.com/questions/73643839
复制相似问题