
Thorsten Ottosen wrote:
I was messing around with enable_if to see if we could detect the number of arguments. But I couldn't find a traits that does that yesterday ... now I see
<boost/function_types/function_arity.hpp>
could help. This way I think we can avoid instantiating result_of until it works.
Note that you cannot use SFINAE based on template `Fun`'s arity since `Fun` is not a template parameter of void_ptr_indirect_fun's operator(). To avoid unnecessary instanciation of result_of, we might need to make operator() a function template and make its return type a dependent type of its template parameters. The following code works fine: #include <boost/static_assert.hpp> #include <boost/type_traits/is_void.hpp> /* ... */ template <typename Type, typename Dummy> struct make_lazy { typedef typename Type::type type; }; template <typename Fun, typename Arg1, typename Arg2 = Arg1> class void_ptr_indirect_fun { /* ... */ template <typename Dummy> typename make_lazy< boost::result_of<const Fun(const Arg1&)> , Dummy >::type operator()(const Dummy* r) const { BOOST_STATIC_ASSERT(boost::is_void<Dummy>::value); BOOST_ASSERT(r != 0); return fun( *static_cast<const Arg1*>(static_cast<const void*>(r)) ); } template <typename Dummy> typename make_lazy< boost::result_of<const Fun(const Arg1&, const Arg2&)> , Dummy >::type operator()(const Dummy* l, const Dummy* r) const { BOOST_STATIC_ASSERT(boost::is_void<Dummy>::value); BOOST_ASSERT(l != 0 && r != 0); return fun( *static_cast<const Arg1*>(static_cast<const void*>(l)) , *static_cast<const Arg2*>(static_cast<const void*>(r)) ); } /* ... */ }; /* ... */ Regards, Michel