
On Tue, Jan 17, 2012 at 5:25 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> wrote:
On Mon, Jan 16, 2012 at 5:34 PM, Nathan Ridge <zeratul976@hotmail.com> wrote:
This can be implemented using a suitable function_type that returns the function type result_type (arg1_type, ...) from a function type, function pointer, function reference, or from a functor which defines the types result_type, arg1_type, ... (as for example boost::function does).
You can also implement it for any function object with a nontemplated operator() even if it doesn't provide arg1_type etc. typedefs, by examining the signature of its operator().
Right! Below I'm wrapping function types, pointers, and references inside a functor type boost::function; if F is instead already a functor, I leave it unchanged (see functor_wrap). Then I manipulate the type of the functor operator() to generate the function type (see functor_unwrap). That allows me to pass any function type, pointer, reference, or any functor (which defines an operator()) to make_overload (without requiring the functor to typedef result_type, arg1_type, etc) :)
One question: Can I do this even without the TYPEOFs inside deduce_type below?
Simplifying things a bit... but the typeof is still hanging in there :( namespace boost { namespace functional { namespace detail { // Precondition: F is a functor. template<typename F> class functor_type { typedef BOOST_TYPEOF_TPL(&(F::operator())) call_ptr; public: typedef typename boost::function_types::function_type< typename boost::mpl::push_front< typename boost::mpl::pop_front< // Remove functor type (1st). typename boost::function_types::parameter_types< call_ptr>::type >::type , typename boost::function_types::result_type<call_ptr>::type >::type >::type type; }; // Precondition: F is a function type, pointer, reference, or functor. template<typename F> struct function_type { typedef typename boost::mpl::if_<boost::function_types::is_function<F>, boost::mpl::identity<F> , typename boost::mpl::if_<boost::function_types:: is_function_pointer<F>, boost::remove_pointer<F> , typename boost::mpl::if_<boost::function_types:: is_function_reference<F>, boost::remove_reference<F> , // Requires, it's a functor. functor_type<F> >::type >::type >::type ::type type; }; } // namespace detail template<typename F0, typename F1, typename F2> overload< typename detail::function_type<F0>::type , typename detail::function_type<F1>::type , typename detail::function_type<F2>::type
make_overload(F0 f0, F1 f1, F2 f2) { return overload< typename detail::function_type<F0>::type , typename detail::function_type<F1>::type , typename detail::function_type<F2>::type >(f0, f1, f2); }
} } // namespace boost::functional --Lorenzo