我试图包装一个对象,该对象代表由io_service完成的工作。
该作业是任意类型的,并且不必是IO操作。与here相似。
我已经能够发布绑定(bind)的常规函数,但无法发布成员函数。
为什么此代码无法编译:
#include <iostream>
#include "boost/asio.hpp"
#include "boost/thread.hpp"
using namespace std;
namespace asio = boost::asio;
class class_fun1 {
public:
void an_expensive_calculation(int num) {
cout << "an_expensive_calculation: " << num << endl;
}
};
class class_fun2 {
public:
void a_long_running_task(int num) {
for (int x = 0; x < num; ++x)
cout << "a_long_running_task: " << num << endl;
}
};
int main(int argc, char** argv) {
int my_thread_count = 4;
asio::io_service io_service;
asio::io_service::work work(io_service);
boost::thread_group threads;
for (std::size_t i = 0; i < my_thread_count; ++i)
threads.create_thread(boost::bind(&asio::io_service::run, &io_service));
class_fun1 f1();
class_fun2 f2();
io_service.post(boost::bind(&class_fun1::an_expensive_calculation, &f1, 42));
io_service.post(boost::bind(&class_fun2::a_long_running_task, &f2, 123));
threads.join_all();
return 0;
}
虽然这一工程:
#include <iostream>
#include "boost/asio.hpp"
#include "boost/thread.hpp"
using namespace std;
namespace asio = boost::asio;
void an_expensive_calculation(int num) {
cout << "an_expensive_calculation: " << num << endl;
}
void a_long_running_task(int num) {
for (int x = 0; x < num; ++x)
cout << "a_long_running_task: " << num << endl;
}
int main(int argc, char** argv) {
int my_thread_count = 4;
asio::io_service io_service;
asio::io_service::work work(io_service);
boost::thread_group threads;
for (std::size_t i = 0; i < my_thread_count; ++i)
threads.create_thread(boost::bind(&asio::io_service::run, &io_service));
io_service.post(boost::bind(an_expensive_calculation, 42));
io_service.post(boost::bind(a_long_running_task, 123));
threads.join_all();
return 0;
}
我浏览了一些在线教程和文档,据我所知首先应该起作用。我遵循了将成员函数绑定(bind)并将其发布到io_service的准则,但是没有用。
最佳答案
问题是most vexing parse的结果。特别地,以下声明了两个函数:
class_fun1 f1(); // function declaration
class_fun2 f2(); // function declaration
第一个声明一个名为
f1
的函数,该函数不带任何参数,并返回class_func1
的实例。它不声明标识符为class_func1
的f1
实例。 f2
也是如此。要解决此问题,请删除括号,将代码更改为:
class_fun1 f1; // declares a variable
class_fun2 f2; // declares a variable
给定clang的编译器输出消息,有时最好打开编译器警告并尝试对其进行编译。特别是,当尝试使用clang解析原始代码时,它提供了一些helpful output:
main.cpp:35:18: error: empty parentheses interpreted as a function declaration [-Werror,-Wvexing-parse]
class_fun1 f1();
^~
main.cpp:35:18: note: remove parentheses to declare a variable
class_fun1 f1();
同样,由于
boost::asio::work
对象的生命周期,该程序将永远不会终止,因为线程组将永远不会成功加入。若要解决此问题,请考虑在加入线程组之前销毁工作对象,或者在运行工作之前将工作发布到io_service
中。有关何时阻止和解除阻止io_service
的更多详细信息,请考虑阅读this问题。