boost::bind and class member function - c++

Consider following example.
#include <iostream>
#include <algorithm>
#include <vector>
#include <boost/bind.hpp>
void
func(int e, int x) {
std::cerr << "x is " << x << std::endl;
std::cerr << "e is " << e << std::endl;
}
struct foo {
std::vector<int> v;
void calc(int x) {
std::for_each(v.begin(), v.end(),
boost::bind(func, _1, x));
}
void func2(int e, int x) {
std::cerr << "x is " << x << std::endl;
std::cerr << "e is " << e << std::endl;
}
};
int
main()
{
foo f;
f.v.push_back(1);
f.v.push_back(2);
f.v.push_back(3);
f.v.push_back(4);
f.calc(1);
return 0;
}
All works fine if I use func() function. But in real life application I have to use class member function, i.e. foo::func2() in this example. How can I do this with boost::bind ?

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.

While using boost::bind for binding class member functions, the second argument must supply the object context. So your code will work when the second argument is this

Related

store pointers to such functions that can have any return type and also can have different number of parameters of any type [duplicate]

I am trying to create a map with string as key and a generic method as value in C++, but I do not know if that is even possible. I would like to do something like that:
void foo(int x, int y)
{
//do something
}
void bar(std::string x, int y, int z)
{
//do something
}
void main()
{
std::map<std::string, "Any Method"> map;
map["foo"] = &foo; //store the methods in the map
map["bar"] = &bar;
map["foo"](1, 2); //call them with parameters I get at runtime
map["bar"]("Hello", 1, 2);
}
Is that possible? If yes, how can I realise this?
You can type-erase the function types into a container, then provide a template operator(). This will throw std::bad_any_cast if you get it wrong.
N.B. because of the type erasure, you will have to specify exactly matching arguments at the call site, as e.g. std::function<void(std::string)> is distinct from std::function<void(const char *)>, even though both can be called with a value like "Hello".
#include <any>
#include <functional>
#include <map>
#include <string>
#include <iostream>
template<typename Ret>
struct AnyCallable
{
AnyCallable() {}
template<typename F>
AnyCallable(F&& fun) : AnyCallable(std::function(std::forward<F>(fun))) {}
template<typename ... Args>
AnyCallable(std::function<Ret(Args...)> fun) : m_any(fun) {}
template<typename ... Args>
Ret operator()(Args&& ... args)
{
return std::invoke(std::any_cast<std::function<Ret(Args...)>>(m_any), std::forward<Args>(args)...);
}
std::any m_any;
};
void foo(int x, int y)
{
std::cout << "foo" << x << y << std::endl;
}
void bar(std::string x, int y, int z)
{
std::cout << "bar" << x << y << z << std::endl;
}
using namespace std::literals;
int main()
{
std::map<std::string, AnyCallable<void>> map;
map["foo"] = &foo; //store the methods in the map
map["bar"] = &bar;
map["foo"](1, 2); //call them with parameters I get at runtime
map["bar"]("Hello, std::string literal"s, 1, 2);
try {
map["bar"]("Hello, const char *literal", 1, 2); // bad_any_cast
} catch (std::bad_any_cast&) {
std::cout << "mismatched argument types" << std::endl;
}
map["bar"].operator()<std::string, int, int>("Hello, const char *literal", 1, 2); // explicit template parameters
return 0;
}
The most (I cannot say best here) you can do is to use a signature erasure. That mean to convert the pointer to functions to a common signature type, and then convert them back to the correct signature before using them.
That can only be done in very special use cases (I cannot imagine a real world one) and will be highly unsecure: nothing prevent you to pass the wrong parameters to a function. In short: NEVER DO THIS IN REAL WORLD CODE.
That being said, here is a working example:
#include <iostream>
#include <string>
#include <map>
typedef void (*voidfunc)();
void foo(int x, int y)
{
std::cout << "foo " << x << " " << y << std::endl;
}
void bar(std::string x, int y, int z)
{
std::cout << "bar " << x << " " << y << " " << z << std::endl;
}
int main()
{
std::map<std::string, voidfunc> m;
m["foo"] = (voidfunc) &foo;
m["bar"] = (voidfunc)& bar;
((void(*)(int, int)) m["foo"])(1, 2);
((void(*)(std::string, int, int)) m["bar"])("baz", 1, 2);
return 0;
}
It gives as expected:
foo 1 2
bar baz 1 2
I could not find in standard whether this invokes or not Undefined Behaviour because little is said about function pointer conversions, but I am pretty sure that all common compilers accept that, because it only involve function pointers casting.
You cannot store functions with different signatures in a container like map, no matter if you store them as a function pointer or std ::function<WHATEVER>. The information about the signature of the function is one and only one in both cases.
The types for the value in map is one, meaning that the object stored in it are all of the same type.
So if your functions have all the same signature, then it's easy, otherwise, you have to abandon type safety and start walking in a very dangerous realm.
The one in which you erase the type information about the functions stored inside the map.
This translates to something like map<string, void*>.

Store functions with different signatures in a map

I am trying to create a map with string as key and a generic method as value in C++, but I do not know if that is even possible. I would like to do something like that:
void foo(int x, int y)
{
//do something
}
void bar(std::string x, int y, int z)
{
//do something
}
void main()
{
std::map<std::string, "Any Method"> map;
map["foo"] = &foo; //store the methods in the map
map["bar"] = &bar;
map["foo"](1, 2); //call them with parameters I get at runtime
map["bar"]("Hello", 1, 2);
}
Is that possible? If yes, how can I realise this?
You can type-erase the function types into a container, then provide a template operator(). This will throw std::bad_any_cast if you get it wrong.
N.B. because of the type erasure, you will have to specify exactly matching arguments at the call site, as e.g. std::function<void(std::string)> is distinct from std::function<void(const char *)>, even though both can be called with a value like "Hello".
#include <any>
#include <functional>
#include <map>
#include <string>
#include <iostream>
template<typename Ret>
struct AnyCallable
{
AnyCallable() {}
template<typename F>
AnyCallable(F&& fun) : AnyCallable(std::function(std::forward<F>(fun))) {}
template<typename ... Args>
AnyCallable(std::function<Ret(Args...)> fun) : m_any(fun) {}
template<typename ... Args>
Ret operator()(Args&& ... args)
{
return std::invoke(std::any_cast<std::function<Ret(Args...)>>(m_any), std::forward<Args>(args)...);
}
std::any m_any;
};
void foo(int x, int y)
{
std::cout << "foo" << x << y << std::endl;
}
void bar(std::string x, int y, int z)
{
std::cout << "bar" << x << y << z << std::endl;
}
using namespace std::literals;
int main()
{
std::map<std::string, AnyCallable<void>> map;
map["foo"] = &foo; //store the methods in the map
map["bar"] = &bar;
map["foo"](1, 2); //call them with parameters I get at runtime
map["bar"]("Hello, std::string literal"s, 1, 2);
try {
map["bar"]("Hello, const char *literal", 1, 2); // bad_any_cast
} catch (std::bad_any_cast&) {
std::cout << "mismatched argument types" << std::endl;
}
map["bar"].operator()<std::string, int, int>("Hello, const char *literal", 1, 2); // explicit template parameters
return 0;
}
The most (I cannot say best here) you can do is to use a signature erasure. That mean to convert the pointer to functions to a common signature type, and then convert them back to the correct signature before using them.
That can only be done in very special use cases (I cannot imagine a real world one) and will be highly unsecure: nothing prevent you to pass the wrong parameters to a function. In short: NEVER DO THIS IN REAL WORLD CODE.
That being said, here is a working example:
#include <iostream>
#include <string>
#include <map>
typedef void (*voidfunc)();
void foo(int x, int y)
{
std::cout << "foo " << x << " " << y << std::endl;
}
void bar(std::string x, int y, int z)
{
std::cout << "bar " << x << " " << y << " " << z << std::endl;
}
int main()
{
std::map<std::string, voidfunc> m;
m["foo"] = (voidfunc) &foo;
m["bar"] = (voidfunc)& bar;
((void(*)(int, int)) m["foo"])(1, 2);
((void(*)(std::string, int, int)) m["bar"])("baz", 1, 2);
return 0;
}
It gives as expected:
foo 1 2
bar baz 1 2
I could not find in standard whether this invokes or not Undefined Behaviour because little is said about function pointer conversions, but I am pretty sure that all common compilers accept that, because it only involve function pointers casting.
You cannot store functions with different signatures in a container like map, no matter if you store them as a function pointer or std ::function<WHATEVER>. The information about the signature of the function is one and only one in both cases.
The types for the value in map is one, meaning that the object stored in it are all of the same type.
So if your functions have all the same signature, then it's easy, otherwise, you have to abandon type safety and start walking in a very dangerous realm.
The one in which you erase the type information about the functions stored inside the map.
This translates to something like map<string, void*>.

How does a std::function object which return a std::function work when call by operator()?

Sample:
#include "stdafx.h"
#include <functional>
#include <iostream>
#include <string>
std::function<void(int)> Foo()
{
int v = 1;
int r = 2;
auto l = [v, r](int i)
{
std::cout << v << " " << r << " " << i << std::endl;
};
return l;
}
int main()
{
auto func = Foo();
func(3);
return 0;
}
Why func(3) can pass 3 to i which is the formal argument of the lambda in Foo(). I can't think out. thanks.
TL;DR: You don't pass your argument 3 into a function Foo. You pass it to a method of an object func.
A bit more detailed explanation is below.
First of all, I would like to clarify what a lambda is. A lambda in C++ is nothing more than an anonymous functor class, so essentially just a syntactic sugar. A closure is an instance of a lambda type. However, quite often you can hear words "lambda" and "closure" being used interchangeably.
So within your function Foo() you create a closure object l
auto l = [v, r](int i)
{
std::cout << v << " " << r << " " << i << std::endl;
};
which would be technically equivalent to this code:
struct Functor
{
Functor(int v, int r) : v_(v), r_(r) {}
void operator ()(int i) const {
std::cout << v_ << " " << r_ << " " << i << std::endl;
}
private:
int v_;
int r_;
};
Functor l(v, r);
Now, on the next line you return an std::function object.
return l; // actually creates std::function<void(int)>(l) and returns it
So in your main function a func is just an object which stores copies of values v, r obtained during a call to Foo() and defines operator(), similar to the struct above.
Therefore, calling func(3) you actually invoke an object method on a concrete object func, and without syntactic sugar it looks like func.operator()(3).
Here's a live example to illustrate my point.
Hope that helps to resolve your confusion.

Force out of scope boost::bind to fail

I'm trying to create an example of binding a boost::function to a member function that goes out of scope. It is still possible to call this function, even though the object no longer exists.
I need to prove that it is not a correct use and the app needs to fail. But the memory location still seems to be in tact, so I need a way to make it fail.
The other question asked would be: am I right? Is there something I might be missing?
class bad_object {
public:
void fct1() {cout << "Fct 1 called. String value: " << sth << endl;};
void fct2(int i) {cout << "Fct 2 with param " << i << endl;};
string sth;
};
int main()
{
bad_object b;
boost::function<void ()> f1(boost::bind( &bad_object::fct1, b ));
boost::function<void ()> f2(boost::bind( &bad_object::fct2, b, 10 ));
boost::function<void ()> f3;
{
bad_object c;
c.sth = "There once was a cottage";
f3 = boost::bind( &bad_object::fct1, c );
}
// c now goes of scope, f3 should therefore be invalid
f3();
return 0;
}
output as expected.
Fct 1 called. String value:
Fct 2 with param 10
Fct 1 called. String value: There once was a cottage
Perhaps you use weak_ptr: Live On Coliru
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
struct X
{
int foo() const
{
return 42;
}
virtual ~X() {
std::cout << "I'm stepping out here\n";
}
};
int weak_call(int (X::*ptmf)() const, boost::weak_ptr<X> const& wp)
{
auto locked = wp.lock();
if (!locked)
throw boost::bad_weak_ptr();
return ((*locked).*ptmf)();
}
int main()
{
boost::function<int()> bound_foo;
{
auto x = boost::make_shared<X>();
bound_foo = boost::bind(weak_call, &X::foo, boost::weak_ptr<X>(x));
std::cout << "Bound foo returns: " << bound_foo() << "\n";
}
std::cout << "Bound foo returns: " << bound_foo() << "\n";
}
Prints:
Bound foo returns: 42
I'm stepping out here
terminate called after throwing an instance of 'boost::bad_weak_ptr'
what(): tr1::bad_weak_ptr
A more generalized version (that allows n-ary member function, optionally const-qualified) is here (requiring c++11): coliru

Disambiguating calls to functions taking std::functions

The code below doesn't compile on gcc 4.5 because the call to foo is ambiguous. What is the correct way to disambiguate it?
#include <iostream>
#include <functional>
using namespace std;
void foo(std::function<void(int, int)> t)
{
t(1, 2);
}
void foo(std::function<void(int)> t)
{
t(2);
}
int main()
{
foo([](int a, int b){ cout << "a: " << a << " b: " << b << endl;});
}
The best way is to explicitly create a std::function object of the correct type then pass that object to the function:
std::function<void(int, int)> func =
[](int a, int b) { cout << "a: " << a << " b: " << b << endl; }
foo(func);
or inline:
foo(
std::function<void(int, int)>(
[](int a, int b) { cout << "a: " << a << "b: " << b << endl; }
));
std::function has a constructor template that accepts anything:
template<class F> function(F);
Because of this, there's no way for the compiler to know during overload resolution which foo to select: both std::function<void(int)> and std::function<void(int, int)> have a constructor that can take your lambda expression as an argument.
When you pass a std::function object directly, the std::function copy constructor is preferred during overload resolution, so it is selected instead of the constructor template.
Answer for the future: If the capture list is guaranteed to be empty, you can also use ordinary function pointers. In C++0x, a captureless lambda is implicitly convertible to a function pointer. So, you can use something like
void foo(void (*t)(int, int)) { t(1, 2); }
void foo(void (*t)(int)) { t(1); }
and call foo directly with the captureless lambda (or a function pointer with matching type).
Note that this conversion is a very recent addition to the draft language standard (it was added in February of this year), so it is not likely to be widely supported yet. Visual C++ 2010 doesn't support it yet; I don't know about the latest g++.
I've recently been thinking about a similar problem and when looking around for any known solutions I came across this post and lack of solutions for resolving
An alternative solution is to abstract over the functor as a template argument and use decltype to resolve its type. So, the above example would become:
#include <iostream>
#include <functional>
using namespace std;
template<class F>
auto foo(F t) -> decltype(t(1,2))
{
t(1, 2);
}
template<class F>
auto foo(F t) -> decltype(t(2))
{
t(2);
}
int main()
{
foo([](int a, int b){ cout << "a: " << a << " b: " << b << endl;});
}
This works as expected with gcc 4.5.