How to Use Boost Bind with a Member Function

How to use boost bind with a member function

Use the following instead:

boost::function<void (int)> f2( boost::bind( &myclass::fun2, this, _1 ) );

This forwards the first parameter passed to the function object to the function using place-holders - you have to tell Boost.Bind how to handle the parameters. With your expression it would try to interpret it as a member function taking no arguments.

See e.g. here or here for common usage patterns.

Note that VC8s cl.exe regularly crashes on Boost.Bind misuses - if in doubt use a test-case with gcc and you will probably get good hints like the template parameters Bind-internals were instantiated with if you read through the output.

How to use boost::bind to bind a member-function to ANY object

Many subtle tweaks, most simplifications:

Live On Coliru (c++03)

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

class A
{
public:
A() {}

void func1(int i) const { std::cout << __PRETTY_FUNCTION__ << "(" << i << ")\n"; }
void func2(const std::string& s) const { std::cout << __PRETTY_FUNCTION__ << "(" << s << ")\n"; }

static void dispatch(const std::vector<A>& vect, boost::function<void(A const&)> const& func)
{
for ( std::vector<A>::const_iterator iter = vect.begin();
iter != vect.end();
++iter )
{
func(*iter);
}
}
};

int main()
{
std::vector<A> vect(3);

A::dispatch(vect, boost::bind(&A::func1, _1, 3));
A::dispatch(vect, boost::bind(&A::func2, _1, "hello"));
}

Notes

  • Use boost::function<void(A const&)> because you dereference const iterators
  • Use A::dispatch(vect, boost::bind(&A::func1, _1, 3));
  • Mark func1 and func2 const

    void func1(int i) const;
    void func2(std::string const& i) const;

Output:

void a::func1(int) const(3)
void a::func1(int) const(3)
void a::func1(int) const(3)
void a::func2(const std::string &) const(hello)
void a::func2(const std::string &) const(hello)
void a::func2(const std::string &) const(hello)

Passing a member function as a callback, boost::bind, boost::function

Instead of boost::function<int(void)> f = boost::bind(&Organism::getAge, animal); it should be boost::function<int(void)> f = boost::bind(&Organism::getAge, &animal);, because boost::bind creates an internal copy of your object if you do as above.

See boost documentation for boost::bind

How to correctly bind a member function with boost::bind

Issue is you pass a pointer to a boost::function - you need to dereference first:

void Callbackcaller(boost::function<void(const T &)> *Callback_fn)  {
...
(*Callback_fn)(loc_tmp); //pipeline.hpp[96, 18]
};

boost::bind and class member function

You were really, really close:

void calc(int x) {
std::for_each(v.begin(), v.end(),
boost::bind(&foo::func2, this, _1, x));
}

EDIT: oops, so was I. heh.

Although, on reflection, there is nothing really wrong with your first working example. You should really favour free functions over member functions where possible - you can see the increased simplicity in your version.

boost::bind member function as argument inside its own member function

The problem is that the thread function isn't static, so it needs an argument for this (LDServer*). Or you can make it static:

  static void workerThread(boost::shared_ptr<ba::io_service> io_service) {
io_service->run();
}
void createThreads() {
worker_threads.create_thread(
boost::bind(&LDserver::workerThread, io_service));
}

However, all the rampant dynamic allocation, shared ownership and manual threading, as well as the boost bind/shared_ptr instead of standard library are all code smells. If you're using a VeryOldOrBadBook(TM) to learn this from, please compare:

#include <boost/asio.hpp>
namespace net = boost::asio;

class LDserver : public std::enable_shared_from_this<LDserver> {
using executor_type = net::thread_pool::executor_type;

net::thread_pool _ctx{1}; // one thread please
net::strand<executor_type> _strand{_ctx.get_executor()};

public:
~LDserver() {
_ctx.join(); // don't forget to join your threads anyway
}
};

How std::bind works with member functions

When you say "the first argument is a reference" you surely meant to say "the first argument is a pointer": the & operator takes the address of an object, yielding a pointer.

Before answering this question, let's briefly step back and look at your first use of std::bind() when you use

std::bind(my_divide, 2, 2)

you provide a function. When a function is passed anywhere it decays into a pointer. The above expression is equivalent to this one, explicitly taking the address

std::bind(&my_divide, 2, 2)

The first argument to std::bind() is an object identifying how to call a function. In the above case it is a pointer to function with type double(*)(double, double). Any other callable object with a suitable function call operator would do, too.

Since member functions are quite common, std::bind() provides support for dealing with pointer to member functions. When you use &print_sum you just get a pointer to a member function, i.e., an entity of type void (Foo::*)(int, int). While function names implicitly decay to pointers to functions, i.e., the & can be omitted, the same is not true for member functions (or data members, for that matter): to get a pointer to a member function it is necessary to use the &.

Note that a pointer to member is specific to a class but it can be used with any object that class. That is, it is independent of any particular object. C++ doesn't have a direct way to get a member function directly bound to an object (I think in C# you can obtain functions directly bound to an object by using an object with an applied member name; however, it is 10+ years since I last programmed a bit of C#).

Internally, std::bind() detects that a pointer to a member function is passed and most likely turns it into a callable objects, e.g., by use std::mem_fn() with its first argument. Since a non-static member function needs an object, the first argument to the resolution callable object is either a reference or a [smart] pointer to an object of the appropriate class.

To use a pointer to member function an object is needed. When using a pointer to member with std::bind() the second argument to std::bind() correspondingly needs to specify when the object is coming from. In your example

std::bind(&Foo::print_sum, &foo, 95, _1)

the resulting callable object uses &foo, i.e., a pointer to foo (of type Foo*) as the object. std::bind() is smart enough to use anything which looks like a pointer, anything convertible to a reference of the appropriate type (like std::reference_wrapper<Foo>), or a [copy] of an object as the object when the first argument is a pointer to member.

I suspect, you have never seen a pointer to member - otherwise it would be quite clear. Here is a simple example:

#include <iostream>

struct Foo {
int value;
void f() { std::cout << "f(" << this->value << ")\n"; }
void g() { std::cout << "g(" << this->value << ")\n"; }
};

void apply(Foo* foo1, Foo* foo2, void (Foo::*fun)()) {
(foo1->*fun)(); // call fun on the object foo1
(foo2->*fun)(); // call fun on the object foo2
}

int main() {
Foo foo1{1};
Foo foo2{2};

apply(&foo1, &foo2, &Foo::f);
apply(&foo1, &foo2, &Foo::g);
}

The function apply() simply gets two pointers to Foo objects and a pointer to a member function. It calls the member function pointed to with each of the objects. This funny ->* operator is applying a pointer to a member to a pointer to an object. There is also a .* operator which applies a pointer to a member to an object (or, as they behave just like objects, a reference to an object). Since a pointer to a member function needs an object, it is necessary to use this operator which asks for an object. Internally, std::bind() arranges the same to happen.

When apply() is called with the two pointers and &Foo::f it behaves exactly the same as if the member f() would be called on the respective objects. Likewise when calling apply() with the two pointers and &Foo::g it behaves exactly the same as if the member g() would be called on the respective objects (the semantic behavior is the same but the compiler is likely to have a much harder time inlining functions and typically fails doing so when pointers to members are involved).

How to bind a static member function to a boost::function using boost::bind

It will be done as you do for normal functions binding.
For static function you just need to use its class name for to recognize the function by the compiler and skip the this argument since static finctions are bound to class not to the object.
Below is a simple example:

#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
void test(boost::function<bool(int, int)> func)
{
std::cout<<"in test().\n";
bool ret = func(10, 20);
std::cout<<"Ret:"<<ret<<"\n";
}
class Test
{
public:
static bool test2(int a, int b)
{
std::cout<<"in test2().\n";
return a>b;
}
};

int main()
{
test(boost::bind(&Test::test2, _1, _2));
return 0;
}

O/P:
in test().
in test2().
Ret:0

You should not use this as static functions dont have this pointer.

int main()
{
test(boost::bind(&Test::test2, this, _1, _2));-----> Illegal
return 0;
}
Below error will occur:
techie@gateway1:myExperiments$ g++ boost_bind.cpp
boost_bind.cpp: In function âint main()â:
boost_bind.cpp:26: error: invalid use of âthisâ in non-member function

Hope this will help. :-)

Using boost::function and boost::bind to a member variable

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)

Pass and call a member function (boost::bind / boost::function?)

boost::function is a template class, that takes a function signature. You can also use function0, function1, etc.

boost::function< void(uint32_t) >

defines a "callable" that looks like a function, i.e. it takes a single parameter of type uint32_t and returns void.

The appropriate numbered template is function1< void, uint32_t >. These always indicate the return type first, then the parameters in order.

boost::bind is a very special function that deduces the arguments you pass into it and creates a functor for you.

It will not create a void(uint32_t) for you, it will create something that has the pattern of one.

Therefore change your signature to:

void f2(boost::function<void(uint32_t)>);

Then you can call it like this:

f2( boost::bind( &Test::f3, this, _1 ) );

Note the strange _1 is a "placeholder" telling boost::bind where it needs to put in the parameter, in this case the uint32_t



Related Topics



Leave a reply



Submit