= Functor = [[TracNav(TracNav/TOC_Development)]] [[TOC]] == Description == The Functor is a wrapper around a function-pointer. You can call the function by executing the Functor without taking care of the types of parameters and return value. This is achieved by using [wiki:MultiType] to pass arguments. Functor works with (almost) every function. This is possible because of a number of derived templates, one for every possible combination: * Static, member or const member * With or without returnvalue * With or without parameters (up to five parameters are allowed) As you see, this results in a total amount of 3*2*6 = 36 combinations, each of them implemented as a template to allow arbitrary types for classes, returnvalues and parameters. Functor.h implements all those templates by using a macro to avoid annoying code repetition. '''Limitation''': Because Functor uses [wiki:MultiType] to pass the arguments, parameters and return values must be of a [wiki:MultiType# supported type]. == Usage == === Creation === To simplify creation of a new Functor, the helper function '''createFunctor('''''function-pointer''''')''' was created. Without that function, you would have to pick the right template (out of 36 possibilities) and specify all template arguments - quite annoying. But with '''createFunctor''' it's really easy: {{{ int someFunction(float param1, bool param2); Functor* myFunctor = createFunctor(&someFunction); }}} In this case, ''&someFunction'' is the function-pointer of the static function "someFuncton". For memberfunctions, this looks a bit different: {{{ class SomeClass { float someFunction(const std::string& param); }; Functor* myFunctor = createFunctor(&SomeClass::someFunction); }}} Remember: This is just basic function-pointer knowledge, nothing special here. Functor does what it has to do and createFunctor works as usual. '''Important''': createFunctor uses '''new''' to create the Functor and returns a pointer. If you are responsible for the pointer, you have to delete the Functor after usage. === Call === To call the function, just use operator() and pass the arguments as if you would call the function-pointer directly: {{{ void someFunction(int value); Functor* myFunctor = createFunctor(&someFunction); (*myFunctor)(10); // equivalent to someFunction(10); }}} === Returnvalue === If your function returns a value, use '''getReturnvalue()''': {{{ int doubleValue(int value) { return value*2; } Functor* myFunctor = createFunctor(&doubleValue); (*myFunctor)(10); // equivalent to doubleValue(10); int result = myFunctor->getReturnvalue(); // result = 20 }}} === Information === There are some functions returning some information about the function: * '''getParamCount()''': Returns the amount of parameters the function takes * '''hasReturnvalue()''': Returns true if the function returns a value * '''getType()''': Returns the type of the function as an enum: FT_MEMBER, FT_CONSTMEMBER, FT_STATIC * '''getTypenameParam('''''param number (0-4)''''')''': Returns the typename of the given parameter as a string * '''getTypenameReturnvalue()''': Returns the typename of the returnvalue as a string == Types == There are two types of Functors: Functors for static functions and Functors for member functions. The following sections explain the difference. === FunctorStatic === C++ knows two types of static functions: Static functions in a class: {{{ class SomeClass { static void someFunction(); }; }}} And C functions outside of a class: {{{ void someOtherFunction(); }}} Both types are covered by FunctorStatic. FunctorStatic is in fact just a Functor, but you can use it to force static functions: {{{ class SomeClass { static void staticFunction(); void nonstaticFunction(); }; FunctorStatic* functor1 = createFunctor(&SomeClass::staticFunction); // this works FunctorStatic* functor2 = createFunctor(&SomeClass::nonstaticFunction); // this fails }}} However, this would work: {{{ Functor* functor2 = createFunctor(&SomeClass::nonstaticFunction); }}} === FunctorMember === There are two types of member functions: constant and non-constant. {{{ class SomeClass { void constFunction() const; void nonconstFunction(); }; }}} Both types are covered by FunctorMember, but in some cases you have to be aware of the intern difference. FunctorMember is in fact just a Functor, but it needs an object to call the function. Just pass the object in front of the arguments when calling the function: {{{ class SomeClass { void someFunction(int value); }; SomeClass* object = new SomeClass(); FunctorMember* functor = createFunctor(&SomeClass::someFunction); (*functor)(object, 10); // this is equivalent to object->someFunction(10); }}} You can bind an object to a Functor by adding the object with '''setObject('''''object''''')'''. If an object is bound to a Functor, you can call the functor without passing the object again: {{{ class SomeClass { void someFunction(int value); }; SomeClass* object = new SomeClass(); FunctorMember* functor = createFunctor(&SomeClass::someFunction); function->setObject(object); // binds object to the Functor (*functor)(10); // this is equivalent to object->someFunction(10); }}} Note: If you add a constant object, you can only call the Functor if the assigned function-pointer leads to a constant function too. == Template and ambiguity == == Examples ==