Files CCore/inc/FunctorType.h CCore/src/FunctorType.cpp
Functor Init Pattern is widely used in CCore. In the modern C++ functors are commonly used. In CCore we often do it in the following manner:
template <class FuncInit> void Call(FuncInit func_init) { FunctorTypeOf<FuncInit> func(func_init); func(); // call the functor }
I.e. the argument is not used directly as a functor. Instead we create the functor object inside a function from the provided argument and then call it. FunctorTypeOf<FuncInit> is a template typedef, defined in the header FunctorType.h. It defines the exact type of the functor object. The rule is simple: if the type FuncInit defines the inner type FunctorType, then this type is a functor type. Otherwise FuncInit itself is a functor type.
FunctorTypeOf<FuncInit> == typename FuncInit::FunctorType OR FunctorTypeOf<FuncInit> == FuncInit
So if the FuncInit is a "usual functor", then Call just call the copy of it. But the more complicated scenario is possible:
struct FuncInit // lightweight initializer { .... class FunctorType : NoCopy // heavy functor { public: FunctorType(FuncInit func_init); ~FunctorType(); void operator () (); }; }; .... FuncInit func_init; Call(func_init);
In this example the "heavy" functor is created inside Call() from a lightweight initializer. The functor may be non-copyable and may have a non-trivial destructor (it may allocate and dispose resources temporary).
The helper class FunctorRefType is designed to pass a functor reference:
template <class T>
struct FunctorRefType
{
T *obj;
explicit FunctorRefType(T &obj_) : obj(&obj_) {}
using FunctorType = T & ;
operator FunctorType() const { return *obj; }
};
Use the Creator function FunctorRef() to create an object of type FunctorRefType.
template <class T>
FunctorRefType<T> FunctorRef(T &obj) { return FunctorRefType<T>(obj); }