Boost.Bind'ing 成员函数并将其发布到 io_service

Boost.Bind'ing a member function and posting it to io_service

我正在尝试包装一个代表 io_service 完成的工作的对象。

作业是任意类型的,不一定是IO操作。类似于 here.

中描述的内容

我已经能够post绑定常规函数,但无法post成员函数.

为什么这段代码无法编译:

#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;
}

我浏览了一些在线教程和文档,据我所知,首先应该可行。我遵循了绑定成员函数的指南并将其 posting 到 io_service,但它不起作用。

问题是 most vexing parse 的结果。特别是,以下声明了两个函数:

class_fun1 f1(); // function declaration
class_fun2 f2(); // function declaration

第一个声明了一个名为 f1 的函数,该函数不带参数,returns 是 class_func1 的一个实例。它不声明标识符为 f1class_func1 的实例。类似的情况也适用于 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 object's lifetime, the program will never terminate, as the thread group will never be successfully joined. To resolve this, consider destroying the work object before joining the thread group or posting work into the io_service before running it. For more details on when the io_service will block and unblock, consider reading this 问题。