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

时间:2015-08-29 05:22:27

标签: c++ c++11 boost boost-asio boost-bind

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

作业属于任意类型,不必是IO操作。与描述的内容类似here

我能够发布绑定的 常规功能 ,但无法发布 成员函数

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

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

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

1 个答案:

答案 0 :(得分:3)

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

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

第一个声明一个名为f1的函数,该函数不带参数并返回class_func1的实例。它不会声明标识为class_func1的{​​{1}}实例。类似的情况也适用于f1

要解决此问题,请删除括号,将代码更改为:

f2

鉴于clang的编译器输出消息,有时可以调高编译器警告并尝试使用它进行编译。特别是,当尝试使用clang解析原始代码时,它会提供一些helpful output

class_fun1 f1; // declares a variable
class_fun2 f2; // declares a variable

此外,由于boost::asio::work对象的生命周期,程序永远不会终止,因为线程组永远不会成功加入。要解决此问题,请考虑在加入线程组之前销毁工作对象,或者在运行之前将工作发布到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(); 。有关io_service阻止和取消阻止的详细信息,请考虑阅读this问题。