Hi! I want to ask, does C++0x going to provide delegate ? If no, tell me what is the best way (most efficient) to use delegation in C++ ? Boost.Signals ? FastDelegate ? Or something other?
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)
.
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);
}
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 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) );