Here's a minimalistic example:
template <class F> struct Decomposer; template <class R, class A> struct Decomposer<R (A)> { typedef R return_type; typedef A argument_type; }; template <class F> struct my_function { typedef typename Decomposer<F>::return_type return_type; typedef typename Decomposer<F>::argument_type argument_type; return_type operator() (argument_type arg) const { return (*impl)(arg); } template <class From> my_function(From &&from) { struct ConcreteImpl : Impl { typename std::remove_reference<From>::type functor; ConcreteImpl(From &&functor) : functor(std::forward<From>(functor)) {} virtual return_type operator() (argument_type arg) const override { return functor(arg); } }; impl.reset(new ConcreteImpl(std::forward<From>(from))); } private: struct Impl { virtual ~Impl() {} virtual return_type operator() (argument_type arg) const = 0; }; std::unique_ptr<Impl> impl; };
The basic idea is to use type erasure to store the actual closure without knowing its type: see virtual Impl::operator() and a locally defined holder of type ConcreteImpl .
Living example
source share