C ++ Boost函数回调。如何调用函数作为回调并在内部传递params?

时间:2016-12-23 11:13:49

标签: c++ function boost callback

我有课程Manager和课程SchedulerManagerScheduler个实例。 Manager启动SchedulerScheduler做某事,而Scheduler必须异步将结果返回Manager。我怎么能在下面的例子中做到这一点?

class Manager{
private:
    Scheduler *mScheduler;

public:
    Manager(){
        mScheduler = new Scheduler(boost::bind(&Manager::acceptResult, this));
        mScheduler->run();
    }

    void acceptResult(Result::Shared result){
        //do something with result, it's doesn't matter=)
    }
};

typedef boost::function<void()> callback;

class Scheduler {
private:
    callback mManagerCallback;

public:
    Scheduler(callback call){
        mManagerCallback = call;
    }

    void run(){
        //some logic
        mManagerCallback(result);
    }

}

typedef boost::posix_time::ptime Timestamp;
typedef boost::posix_time::time_duration Duration;
typedef uint64_t microseconds_timestamp;

class CommandResult {
public:
    typedef shared_ptr<const CommandResult> SharedConst;

private:
    CommandUUID mCommandUUID;
    uint16_t mResultCode;
    Timestamp mTimestampCompleted;
    string mResultInformation;

public:
    CommandResult(
            const CommandUUID &commandUUID,
            const uint16_t resultCode);

    CommandResult(
            const CommandUUID &commandUUID,
            const uint16_t resultCode,
            string &resultInformation);

    const CommandUUID &commandUUID() const;

    const uint16_t resultCode() const;

    const Timestamp &timestampCompleted() const;

    const string serialize() const;

};

CommandResult与示例中的结果相同。

我需要在Scheduler生成结果时,在方法run()中调用Manager方法acceptResult()并将结果作为参数传递。我是C ++的新手,我不知道该怎么做。

1 个答案:

答案 0 :(得分:2)

首先,您必须使回调可以获取参数:

typedef boost::function<void(CommandResult::SharedConst)> callback;

然后你需要在绑定中匹配该签名。看起来您希望将结果保留为Scheduler::run()逻辑中的绑定,所以让我们使用占位符:

 mScheduler = new Scheduler(boost::bind(&Manager::acceptResult, this, ::_1));

现在在你的逻辑中,你以某种方式得到一个结果,然后你把它传递给回调:

void run(){
    boost::uuids::random_generator rgen;
    CommandResult::SharedConst result(new CommandResult(rgen(), 404u, "Not found"));
    //some logic
    mManagerCallback(result);
}

完整演示: Live On Coliru (C++03)

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/random_generator.hpp>

typedef boost::posix_time::ptime Timestamp;
typedef boost::posix_time::time_duration Duration;
typedef uint64_t microseconds_timestamp;

typedef boost::uuids::uuid CommandUUID;

class CommandResult {
public:
    typedef boost::shared_ptr<const CommandResult> SharedConst;

private:
    CommandUUID mCommandUUID;
    uint16_t mResultCode;
    Timestamp mTimestampCompleted;
    std::string mResultInformation;

public:
    CommandResult(
            const CommandUUID &commandUUID,
            const uint16_t resultCode,
            std::string const &resultInformation = "")
      : mCommandUUID(commandUUID),
        mResultCode(resultCode),
        mTimestampCompleted(boost::posix_time::second_clock::local_time()),
        mResultInformation(resultInformation)
    { }

    const CommandUUID &commandUUID() const { return mCommandUUID; }
    uint16_t resultCode() const { return mResultCode; }
    const Timestamp &timestampCompleted() const { return mTimestampCompleted; }
};

typedef boost::function<void(CommandResult::SharedConst)> callback;

class Scheduler {
private:
    callback mManagerCallback;

public:
    Scheduler(callback call){
        mManagerCallback = call;
    }

    void run(){
        boost::uuids::random_generator rgen;
        CommandResult::SharedConst result(new CommandResult(rgen(), 404u, "Not found"));
        //some logic
        mManagerCallback(result);
    }
};

#include <iostream>

class Manager{
private:
    Scheduler *mScheduler;

public:
    Manager(){
        //mScheduler = new Scheduler([this](CommandResult::SharedConst result) { acceptResult(result); });
        mScheduler = new Scheduler(boost::bind(&Manager::acceptResult, this, ::_1));
        mScheduler->run();
    }

    void acceptResult(CommandResult::SharedConst result){
        //do something with result, it's doesn't matter=)
        std::cout << "Accepted: " << result->commandUUID() << ", " << result->resultCode() << ": " << result->timestampCompleted() << " \n";
    }
};

int main() {
    Manager m;
}

打印:

Accepted: cf946fb0-49f3-425a-8235-558d19bf6f8d, 404: 2016-Dec-23 12:18:01 

奖金:C ++ 11

Bind有点不合时宜(虽然我有时很喜欢它,对于罕见的工作),所以考虑使用lambda代替:

mScheduler = new Scheduler([this](CommandResult::SharedConst result) { acceptResult(result); });