Question

I'm trying to create a boost::function that allows setting of a member variable of an object. I've created the simplest example I can think of to get across what I'm trying (and failing) to do. I feel like I have a grasp of boost::bind, but I'm new to boost and I believe I'm using boost::function incorrectly.

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

class Foo
{
public:
    Foo() : value(0) {}

    boost::function<void (int&)> getFcn()
    {
        return boost::function<void (int&)>( boost::bind<void>( Foo::value, this, _1 ) );
    }

    int getValue() const    { return value; }

private:
    int value;
};

int main(int argc, const char * argv[])
{
    Foo foo;

    std::cout << "Value before: " << foo.getValue();

    boost::function<void (int&)> setter = foo.getFcn();
    setter(10);     // ERROR: No matching function for call to object of type 'boost::function<void (int &)>'
                    // and in bind.hpp: Called object type 'int' is not a function or function pointer

    std::cout << "Value after: " << foo.getValue();

    return 0;
}

I'm having the error on line 28, where I want to use the function to set Foo::value to 10. Am I just going about this whole thing wrong? Should I just be passing back an int* or something instead of using boost for all of this? The reason I'm calling 'getFcn()' is because in my actual project I'm using a messaging system, and if the object with the data I want is no longer there, getFcn would return an empty boost::function. But I guess with an int* I could just return NULL if nothing was found.

Was it helpful?

Solution

This boost::bind<void>( Foo::value, this, _1 ) in your code is essentially using Foo::value as a member function. Which is wrong. Foo::value is not a function.

Lets build this step by step:

class Foo
{
    ...
    boost::function< void (Foo*, int) > getFcn ()
    {
        return boost::function< void (Foo*, int) >( &Foo::setValue );
    }

    void setValue (int v)
    {
        value = v;
    }
    ...
}

int main ()
{
    ...
    boost::function< void (Foo*, int) > setter = foo.getFcn();
    setter( &foo, 10);
    ...
}

So here the function takes this object explicitly. Let's use boost.bind to bind this as first parameter.

class Foo
{
    ...
    boost::function< void (int) > getFcn ()
    {
        return boost::bind(&Foo::setValue, this, _1);
    }

    void setValue (int v)
    {
        value = v;
    }
    ...
}

int main ()
{
    ...
    boost::function< void (int) > setter = foo.getFcn();
    setter( 10);
    ...
}

(untested code)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top