How to use boost bind with a member function - c++

The following code causes cl.exe to crash (MS VS2005).
I am trying to use boost bind to create a function to a calls a method of myclass:
#include "stdafx.h"
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <functional>
class myclass {
public:
void fun1() { printf("fun1()\n"); }
void fun2(int i) { printf("fun2(%d)\n", i); }
void testit() {
boost::function<void ()> f1( boost::bind( &myclass::fun1, this ) );
boost::function<void (int)> f2( boost::bind( &myclass::fun2, this ) ); //fails
f1();
f2(111);
}
};
int main(int argc, char* argv[]) {
myclass mc;
mc.testit();
return 0;
}
What am I doing wrong?

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.

Boost.Bind is a library that simplifies and generalizes capabilities that originally required std::bind1st() and std::bind2nd()
Example 1.1: std::for_each() with a compatible function
#include <vector>
#include <algorithm>
#include <iostream>
void print(int i)
{
std::cout << i << '\n';
}
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), print);
}
The third parameter of std::for_each() is a function or function object that expects a sole parameter. In Example 1.1, std::for_each() passes the numbers in the container v as sole parameters, one after another, to print().
If you need to pass in a function whose signature doesn’t meet the requirements of an algorithm, it gets more difficult. For example, if you want print() to accept an output stream as an additional parameter, you can no longer use it as is with std::for_each().
Example 1.2. std::for_each() with std::bind1st()
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
class print : public std::binary_function<std::ostream*, int, void>
{
public:
void operator()(std::ostream *os, int i) const
{
*os << i << '\n';
}
};
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), std::bind1st(print{}, &std::cout));
}
Like Example 1.1, Example 1.2 writes all numbers in v to standard output. However, this time, the output stream is passed to print() as a parameter. To do this, the function print() is defined as a function object derived from std::binary_function.
With Boost.Bind, you don’t need to transform print() from a function to a function object. Instead, you use the function template boost::bind(), which is defined in boost/bind.hpp.
Example 1.3: std::for_each() with boost::bind()
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
void print(std::ostream *os, int i)
{
*os << i << '\n';
}
int main()
{
std::vector<int> v{1, 3, 2};
std::for_each(v.begin(), v.end(), boost::bind(print, &std::cout, _1));
}
Example 1.3 uses print() as a function, not as a function object. Because print() expects two parameters, the function can’t be passed directly to std::for_each(). Instead, boost::bind() is passed to std::for_each() and print() is passed as the first parameter to boost::bind().
Since print() expects two parameters, those two parameters must also be passed to boost::bind(). They are a pointer to std::cout and _1.
_1 is a placeholder. Boost.Bind defines placeholders from _1 to _9. These placeholders tell boost::bind() to return a function object that expects as many parameters as the placeholder with the greatest number. If, as in Example 1.3, only the placeholder _1 is used, boost::bind() returns a unary function object – a function object that expects a sole parameter. This is required in this case since std::for_each() passes only one parameter.
std::for_each() calls a unary function object. The value passed to the function object – a number from the container v – takes the position of the placeholder _1. boost::bind() takes the number and the pointer to std::cout and forwards them to print().
Please note that boost::bind(), like std::bind1st() and std::bind2nd(), takes parameters by value. To prevent the calling program from trying to copy std::cout, print() expects a pointer to a stream. Boost.Ref provides a function which allows you to pass a parameter by reference.
Example 1.4 illustrates how to define a binary function object with boost::bind(). It uses the algorithm std::sort(), which expects a binary function as its third parameter.
Example 1.4. std::sort() with boost::bind()
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
bool compare(int i, int j)
{
return i > j;
}
int main()
{
std::vector<int> v{1, 3, 2};
std::sort(v.begin(), v.end(), boost::bind(compare, _1, _2));
for (int i : v)
std::cout << i << '\n';
}
In Example 1.4, a binary function object is created because the placeholder _2 is used. The algorithm std::sort() calls this binary function object with two values from the container v and evaluates the return value to sort the container. The function compare() is defined to sort v in descending order.
Since compare() is a binary function, it can be passed to std::sort() directly. However, it can still make sense to use boost::bind() because it lets you change the order of the parameters. For example, you can use boost::bind() if you want to sort the container in ascending order but don’t want to change compare()
Example 1.5. std::sort() with boost::bind() and changed order of placeholders
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
bool compare(int i, int j)
{
return i > j;
}
int main()
{
std::vector<int> v{1, 3, 2};
std::sort(v.begin(), v.end(), boost::bind(compare, _2, _1));
for (int i : v)
std::cout << i << '\n';
}

The following works for me.
class test_component
{
private:
void on_wait_complete(const int i);
};
void test_component::on_wait_complete (const int i)
{
cout << "on_wait_complete was called" << endl;
return;
}
int main()
{
// timerPtr_ is a variable declared in class test_component.
timerPtr_->async_wait(boost::bind(&test_component::on_wait_complete, this, _1));
}

Related

Converting pointer to member function to std::function

I have a slightly convoluted use case of passing a member function pointer to an outside function which is then called again by a member function (Don't ask!). I'm learning about std::function and std::mem_fn but I can't seem to be able to convert my old school function pointer
void (T::*func)(int) to a std::function<void (T::*)(int) func>
in the code below, I'd like to be able to pass a std::function to memFuncTaker in the call from anotherMember
#include "class2.hpp"
#include <iostream>
class outer{
public:
void aMember(int a){
std::cout << a <<std::endl;
}
void anotherMember(double){
memFuncTaker(this, &outer::aMember);
}
};
template<class T>
void memFuncTaker(T* obj , void (T::*func)(int) ){
(obj->*func)(7);
}
When you bind std::function to a non-static member function pointer, it "reveals" the hidden this parameter, making it the first explicit parameter of the resultant functor. So in your case for outer::aMember you'd use std::function<void(outer *, int)> and end up with a two-parameter functor
#include <functional>
#include <iostream>
template<class T>
void memFuncTaker(T *obj , std::function<void(T *, int)> func){
func(obj, 7);
}
class outer{
public:
void aMember(int a){
std::cout << a <<std::endl;
}
void anotherMember(double){
memFuncTaker(this, std::function<void(outer *, int)>{&outer::aMember});
}
};
int main() {
outer o;
o.anotherMember(0);
}
http://coliru.stacked-crooked.com/a/5e9d2486c4c45138
Of course, if you prefer, you can bind the first argument of that functor (by using std::bind or lambda) and thus "hide" it again
#include <functional>
#include <iostream>
using namespace std::placeholders;
void memFuncTaker(std::function<void(int)> func){
func(7);
}
class outer{
public:
void aMember(int a){
std::cout << a <<std::endl;
}
void anotherMember(double){
memFuncTaker(std::function<void(int)>(std::bind(&outer::aMember, this, _1)));
}
};
int main() {
outer o;
o.anotherMember(0);
}
Note that in this version memFuncTaker no longer has to be a template (which happens to be one of the primary purposes of std::function - employ type erasure techniques to "de-templatize" the code).

C++ - compilation fails on calling overloaded function in std::thread

Consider the following scenario:
// utils.h
#include <string>
#include <list>
namespace Utils {
void do_something(int a, std::list<int> *b);
void do_something(int a, std::list<std::string> *b);
};
// utils.cpp
#include "utils.h"
void Utils::do_something(int a, std::list<int> *b) {
}
void Utils::do_something(int a, std::list<std::string> *b) {
}
// main.cpp
#include <thread>
#include <list>
#include "utils.h"
int main() {
std::list<int> list;
std::thread t(Utils::do_something, 17, &list);
t.join();
return 0;
}
When I compile it, I get the following error:
error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, int, std::list<int>*)'
Any idea what I'm doing wrong? Before I added the overloading function that gets std::list<std::string>*, it did compile well.
The issue here is even though you pass the parameters to std::thread it does not use those to try and determine the function passed to it. It tries to resolve the function type in isolation. When it does so, it sees there are two different versions and so it stops, as it does not know which one you want.
Unfortunately You are going to have to tell the compiler which function you want to use. You can do that by casting the function to the specific function pointer you want.
Instead of doing that though you can use a lambda to make this easy by allowing overload resolution to take place in a regular function call like
std::thread t([](auto first, auto second){ return Utils::do_something(first, second); }, 17, &list);
This will also work well with member functions as you just capture the object to call the function on with the capture list of the lambda. That saves you from having to pass that object to std::thread or using std::bind.
You can use a static_cast to disambiguate the overloads...
std::thread t(static_cast<void(*)(int, std::list<int> *)>(&Utils::do_something), 17, &list);

Difference between std::logical_not and std::not1?

Please explain with examples when to use std::logical_not and when std::not1!
According to documentation, the former is a "unary function object class" while the latter "constructs a unary function object". So at the end of the day both construct a unary function object, don't they?
Both are functors (a class with an operator()), but differ slightly on what they negate:
std::logical_not<T>::operator() returnsT::operator!(). Semantically, it sees T as a value and negates it.
std::not1<T>::operator() returns !(T::operator()(T::argument_type&)). Semantically, it sees T as a predicate and negates it.
std::not1<T> is a generalization of std::logical_not for more complex use case.
Please explain with examples when to use std::logical_not and when std::not1
Use std::logical_not whenever you can. Use std::not1 whenever your first option is out. The example on en.cppreference.com gives a case where std::not1 is necessary:
#include <algorithm>
#include <numeric>
#include <iterator>
#include <functional>
#include <iostream>
#include <vector>
struct LessThan7 : std::unary_function<int, bool>
{
bool operator()(int i) const { return i < 7; }
};
int main()
{
std::vector<int> v(10);
std::iota(begin(v), end(v), 0);
std::cout << std::count_if(begin(v), end(v), std::not1(LessThan7())) << "\n";
//same as above, but use a lambda function
std::function<int(int)> less_than_9 = [](int x){ return x < 9; };
std::cout << std::count_if(begin(v), end(v), std::not1(less_than_9)) << "\n";
}

Using erase-remove idiom for function<void()>

Stacked people.
Iam trying to implement an observer(esque?) pattern for my program. I have a component which stores what functions should be called if an event occours. My prolem is that i dont know how should i erase my function from the container, if the need arises. Tried storing the functions by reference, but iam not sure how to do that(or if thats possible.)
#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
enum class EVENT_TYPE{
anEvent
};
class EventableComponent{
map<EVENT_TYPE, vector<function<void()>>> listeners;
public:
void trigger(EVENT_TYPE _et){
for(auto& it : listeners[_et]){
it();
}
}
void registerListener(EVENT_TYPE _et, function<void()> _fn){
listeners[_et].push_back(_fn);
};
void removeListener(EVENT_TYPE _et, function<void()> _fn){
//error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::function<void (void)>'
//(or there is no acceptable conversion)
listeners[_et].erase(remove(listeners[_et].begin(), listeners[_et].end(), _fn), listeners[_et].end());
};
};
int main(){
EventableComponent ec;
// this would become a member function for a class somewhere down the line
auto fn = [](){cout << "Hello.\n"; };
ec.registerListener(EVENT_TYPE::anEvent, fn);
ec.trigger(EVENT_TYPE::anEvent);
ec.removeListener(EVENT_TYPE::anEvent, fn);
ec.trigger(EVENT_TYPE::anEvent);
cin.get();
return 0;
};
Your problem can be reduced to the fact that two std::function instances cannot be compared for equality. std::remove requires operator==, and std::function does not have it. See "Why is std::function not equality comparable?".
Consider the following situation.
Let's say you defined two lambdas in your main:
auto fn = [](){cout << "Hello.\n"; };
auto fn2 = [](){cout << "Hello.\n"; };
Now, are those two equal or not? They do the same thing, but perhaps this is sheer coincidence. Would they become unequal if the second "Hello" became "Hello2"? Would they become unequal if the second one was no longer a lambda but a real function void f()?
The thing is that there can be no generally useful definition of equality for function objects, so it's up to you to define what equality really means in the context of your program.
You have several options to solve the problem at hand. One would be to operate on pointers to std::function objects. Pointers can be compared, and proper use of std::unique_ptr makes sure that deallocation is handled correctly.
Or you assign an identifier to every std::function you use. See the following modified example of your code in which direct storage of std::function<void()> in the vector is replaced with a custom type EventFunction that maps an int to the function object. The example uses std::remove_if to compare only the ints:
#include <map>
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
enum class EVENT_TYPE{
anEvent
};
struct EventFunction {
function<void()> f;
int id;
};
class EventableComponent{
map<EVENT_TYPE, vector<EventFunction>> listeners;
public:
void trigger(EVENT_TYPE _et){
for(auto& it : listeners[_et]){
it.f();
}
}
void registerListener(EVENT_TYPE _et, EventFunction _fn){
listeners[_et].push_back(_fn);
};
void removeListener(EVENT_TYPE _et, int function_id){
//error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::function<void (void)>'
//(or there is no acceptable conversion)
listeners[_et].erase(remove_if(listeners[_et].begin(), listeners[_et].end(),
[&](EventFunction const& e) { return e.id == function_id; }), listeners[_et].end());
};
};
int main(){
EventableComponent ec;
// this would become a member function for a class somewhere down the line
auto fn = [](){cout << "Hello.\n"; };
ec.registerListener(EVENT_TYPE::anEvent, EventFunction{ fn, 1 });
ec.trigger(EVENT_TYPE::anEvent);
ec.removeListener(EVENT_TYPE::anEvent, 1);
ec.trigger(EVENT_TYPE::anEvent);
};
Tried storing the functions by reference, but iam not sure how to do
that(or if thats possible.)
It's not possible because you cannot store references in standard-library containers. But I suppose the idea is similar to the one with pointers I mentioned above.

How can I use a boost function to transform the parameter types?

I want to create a boost function object of the following signature:
void (int, boost::uuid);
However, I would like to bind it to a function of the following form:
void (SomeType, boost::uuid)
Where the SomeType argument comes from another function call, so that if I were to call it straight out it would look like:
SomeType myOtherFunction(int);//Prototype
...
myFunction(myOtherFunction(int), myUUID);
In other words, I want the top level function object to completely hide the concept of SomeType and the call to myOtherFunction from the user. Is there a way to do this with one or more boost::function objects created with boost::bind calls?
Functional composition: Live On Coliru
#include <boost/uuid/uuid.hpp>
struct SomeType {};
SomeType myOtherFunction(int) { return SomeType(); }
void foo(SomeType, boost::uuids::uuid) {}
#include <boost/bind.hpp>
#include <boost/function.hpp>
int main()
{
boost::function<void(int, boost::uuids::uuid)> composed;
composed = boost::bind(foo, boost::bind(myOtherFunction, _1), _2);
}
Anyways, in c++11 you'd write [](int i, uuid u) { return foo(myOtherFunction(i), u); } of course