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

发布于 2024-12-13 03:46:38 字数 1407 浏览 5 评论 0原文

这与上一个问题相关: 将 boost::bind 与 boost 结合使用: :function: 检索绑定变量类型

我可以绑定这样的函数:

in .h:

class MyClass
{
    void foo(int a);
    void bar();
    void execute(char* param);
    int _myint;
}

in .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();
}

但如何绑定返回值?即:

在.h中:

class MyClass
{
    double foo(int a);
    void bar();
    void execute(char* param);
    int _myint;
    double _mydouble;
}

在.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;

}

This is related to this previous question: Using boost::bind with boost::function: retrieve binded variable type.

I can bind a function like this:

in .h:

class MyClass
{
    void foo(int a);
    void bar();
    void execute(char* param);
    int _myint;
}

in .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();
}

But how can I bind a return value ? i.e.:

in .h:

class MyClass
{
    double foo(int a);
    void bar();
    void execute(char* param);
    int _myint;
    double _mydouble;
}

in .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;

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蘑菇王子 2024-12-20 03:46:38

如果您想要的是一个返回 void 但在执行此操作之前使用 foo() 的结果为 _myDouble 赋值的空函数,那么仅使用 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
}

If what you want is a nullary function that returns void but assigns a value to _myDouble with the result of foo() before doing so, then you cannot do this easily with just Boost.Bind. However, Boost has another library specifically catered to this sort of thing -- 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
}
朦胧时间 2024-12-20 03:46:38

问题 1:myVector 需要是类成员。
问题 2:myVector 对返回双精度且不带参数的函数感兴趣,这将是 boost::function

然后,将 _mydouble 绑定到foo 的参数,调用 boost::bind(&MyClass::foo, this, MyClass::_mydouble) ,当 foo 为叫。

Boost.Bind 可以提供的最接近的方法是提供 toreturn 作为参数。

#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>

using namespace std;

class Foo {
        int myInt;
        double myDouble;
public:
        Foo() : myInt(3), myDouble(3.141592) { }
        void SetToMyInt(double& param)
        {
                param = myInt;
        }
        void SetToMyDouble(double& param)
        {
                param = myDouble;
        }
        double Execute()
        {
                double toReturn = 2;
                boost::function<void(double&)> f = boost::bind(&Foo::SetToMyDouble, this, _1);
                f(toReturn);
                return toReturn;
        }

};

int main() {
        Foo foo;
        std::cout << foo.Execute() << std::endl;
        return 0;
}

problem 1: myVector needs to be a class member.
problem 2: myVector is interested in functions that return doubles and take no arguments, which would be boost::function<double()>

then, to bind _mydouble to the parameter of foo, call boost::bind(&MyClass::foo, this, MyClass::_mydouble) which should give you a compilation warning about casting a double to an int for when foo is called.

The closest you can come with Boost.Bind is providing the toreturn as a parameter.

#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>

using namespace std;

class Foo {
        int myInt;
        double myDouble;
public:
        Foo() : myInt(3), myDouble(3.141592) { }
        void SetToMyInt(double& param)
        {
                param = myInt;
        }
        void SetToMyDouble(double& param)
        {
                param = myDouble;
        }
        double Execute()
        {
                double toReturn = 2;
                boost::function<void(double&)> f = boost::bind(&Foo::SetToMyDouble, this, _1);
                f(toReturn);
                return toReturn;
        }

};

int main() {
        Foo foo;
        std::cout << foo.Execute() << std::endl;
        return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文