Does C++11 provide delegates?
If not, what is the best (most efficient) way to do something similar in C++? Boost.Signals? FastDelegate? Something else?
You don't need c++0x. in <functional>
you have bind1st
bind2nd
mem_fun
and mem_fun_ref
. You also have Boost.Bind which generalizes all of the above functions (IIRC).
Going from memory ...
vector<Foo> foo = makeVector();
vector<Foo*> foop = makeVectorP();
vector<Bar> bar1,bar2,bar3,bar4;
transform( foo.begin(), foo.end(), back_inserter( bar1 ), mem_fun_ref(&Foo::getBar) );
transform( foop.begin(), foop.end(), back_inserter( bar2 ), mem_fun(&Foo::getBar) );
transform( foo.begin(), foo.end(), back_inserter( bar3 ), bind1st(&bar_from_foo) );
transform( foo.begin(), foo.end(), back_inserter( bar4 ), boost::bind(&bar_from_foo, _1) );
The C mechanism has always been function pointer & baton (except for qsort() and bsearch() which didn't take a baton).
So one would always pass the class object as the baton.
E.G.:
class tp {
public:
tp() { n = 0; }
void m(int z) { printf("%d is %d\n", n++, z++); }
int n;
};
void higher_func(int *opx, int cnt, void *handler(int itm, void *baton), void *baton)
{
for (int i = 0; i < cnt; i++)
handler(opx[itm], baton);
}
/* You would need to provide this stub -- potentially templateable */
void translate_baton(int itm, void *baton) { ((tp *)baton)->m(itm); }
/* used like so: */
int main()
{
int array[7];
//...
tp cx;
higher_func(array, 7, translate_baton, &cx);
}
Though std::function
works nicely, I would like to point out this nice piece of delegate code, written here (including example usage!). Following the references and answers there you can read all about how this Delegate
class is constructed and why it may be faster than std::function
.
Note also my question here for a problem I encountered with it on VS 2015.
You don't necessarily need to wait for C++0x. You can implement Delegates almost as well in the current C++03 standard.
You simply have to overload the operator (), so as you can call MyObjectFunctor functor; functor();
and since the functor is an object, you can pass it as a delegate/object into functions;
the current version of the STL defines the header <algorithm>
that provides functions ready to be used with Functors/Lambdas/Delegates.
simple example of a functor.
struct FunctorDelegate
{
// as so to delegate as a function that takes an int input
void operator()(int)
{
// do what I want
}
};
int main()
{
//... do some stuffs with an std::vector<int> aRange;
FunctorDelegate functor;
std::for_each(aRange.begin(), arange.end(), functor);
}
You can get delegate-like semantics using bind
to bind a member function to a class instance:
#include <functional>
struct C
{
void Foo(int) { }
};
void Bar(std::function<void(int)> func)
{
func(42); // calls obj.Foo(42)
}
int main()
{
using namespace std::placeholders;
C obj;
Bar(std::bind(&C::Foo, obj, _1));
}
In this example, Bar()
takes anything that has a single int
parameter and that returns void
.
In main()
, we bind a pointer to the member function C::Foo
to the instance of C
named obj
. This gives us an object that can be called with a single int
parameter and which returns void
.
We call Bar()
with this object and Bar()
makes the call obj.Foo(42)
.