1

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.

Nic Foster
  • 2,864
  • 1
  • 27
  • 45

1 Answers1

2

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)

Vikas
  • 8,790
  • 4
  • 38
  • 48
  • I'm trying to avoid having a setter method in the class for every variable I want to do this for. I am looking for a way to alter the variable directly. Can boost::function not be used in that way? – Nic Foster Oct 05 '12 at 21:34
  • 1
    @NicFoster, I believe not. Boost.Function is a wrapper over things that behave like functions. You are trying to wrap it over `int`. – Vikas Oct 05 '12 at 21:58
  • Fair enough, I assumed since you could use bind to bind to member variables that you would be able to use `function` to set those member variables. – Nic Foster Oct 05 '12 at 22:18