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
andfunc2
constvoid 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
Gcc C++ "Hello World" Program -> .Exe Is 500Kb Big When Compiled on Windows. How to Reduce Its Size
C++11 Inheriting Constructors and Access Modifiers
C/C++: Optimization of Pointers to String Constants
When and How to Use Exception Handling
When Is an Object "Out of Scope"
Does Std::List::Remove Method Call Destructor of Each Removed Element
Call to Pure Virtual Function from Base Class Constructor
Is There a Range Class in C++11 for Use with Range Based for Loops
C++ Boost: Undefined Reference to Boost::System::Generic_Category()
What's the Meaning of * and & When Applied to Variable Names
How to Embed a File into an Executable
How to Initialize a Constexpr Reference
What am I Not Understanding About Getline+Strings
How to Use Std::String in a Constexpr
How to Best Handle Dynamic Multi-Dimensional Arrays in C/C++
How to Make Generic Computations Over Heterogeneous Argument Packs of a Variadic Template Function