Boost函数和boost绑定:绑定返回值?

Sma*_*ash 2 c++ boost boost-bind boost-function

这与前一个问题有关:使用boost :: bind和boost :: function:检索绑定变量类型.

我可以绑定一个这样的函数:

在.h:

class MyClass
{
    void foo(int a);
    void bar();
    void execute(char* param);
    int _myint;
}
Run Code Online (Sandbox Code Playgroud)

在.cpp

MyClass::bar()
{
    vector<boost::function<void(void)> myVector;
    myVector.push_back(boost::bind(&MyClass::foo, this, MyClass::_myint);
}
MyClass::execute(char* param)
{
    boost::function<void(void)> f  = myVector[0];
    _myint = atoi(param);
    f();
}
Run Code Online (Sandbox Code Playgroud)

但是如何绑定返回值呢?即:

在.h:

class MyClass
{
    double foo(int a);
    void bar();
    void execute(char* param);
    int _myint;
    double _mydouble;
}
Run Code Online (Sandbox Code Playgroud)

在.cpp

MyClass::bar()
{
    vector<boost::function<void(void)> myVector;
    //PROBLEM IS HERE: HOW DO I BIND "_mydouble"
    myVector.push_back(boost::bind<double>(&MyClass::foo, this, MyClass::_myint);
}
MyClass::execute(char* param)
{
    double returnval;
    boost::function<void(void)> f  = myVector[0];
    _myint = atoi(param);
    //THIS DOES NOT WORK: cannot convert 'void' to 'double'
    // returnval = f();
    //MAYBE THIS WOULD IF I COULD BIND...:
    // returnval = _mydouble;

}
Run Code Online (Sandbox Code Playgroud)

ild*_*arn 6

如果您想要的是一个返回的nullary函数,void但在执行此操作之前_myDouble为结果赋值foo(),那么您只能使用Boost.Bind轻松完成此操作.然而,Boost还有另一个专门针对这类事情的图书馆 - Boost.Phoenix:

#include <iostream>
#include <vector>
#include <boost/function.hpp>
#include <boost/phoenix/phoenix.hpp>

struct MyClass
{
    MyClass() : _myVector(), _myInt(), _myDouble() { }
    void setMyInt(int i);
    void bar();
    void execute();

private:
    double foo(int const a) { return a * 2.; }

    std::vector<boost::function<void()> > _myVector;
    int _myInt;
    double _myDouble;
};

void MyClass::setMyInt(int const i)
{
    _myInt = i;
}

void MyClass::bar()
{
    using boost::phoenix::bind;

    _myVector.push_back(
        bind(&MyClass::_myDouble, this) =
            bind(&MyClass::foo, this, bind(&MyClass::_myInt, this))
    );
}

void MyClass::execute()
{
    if (_myVector.empty())
        return;

    _myVector.back()();
    double const returnval = _myDouble;
    std::cout << returnval << '\n';
}

int main()
{
    MyClass mc;
    mc.bar();

    mc.setMyInt(21);
    mc.execute();      // prints 42
    mc.setMyInt(3);
    mc.execute();      // prints 6  (using the same bound function!)
                       // i.e., bar has still only been called once and
                       // _myVector still contains only a single element;
                       // only mc._myInt was modified
}
Run Code Online (Sandbox Code Playgroud)