
Ian McCulloch wrote:
Peter Dimov wrote:
No, you don't have to know this in advance. It is up to the implementation or specialization of result_of<F(...)> to handle these cases and return the correct result.
I'm not sure what you mean here. Do you mean that I should make sure that F::result<F(int, int>) and F::result<F(int const&, int)> are both defined?
Yes, if you F can be called with an rvalue of type int and with an lvalue of type const int. [...]
#include <boost/utility/result_of.hpp>
// some example function that passes by const_reference template <typename T> struct negate { typedef T const& argument_type; typedef T result_type;
result_type operator()(argument_type x) const { return -x; } };
// but we don't want to have to specify the parameter types by hand struct negate_f { template <typename T> struct result {};
template <typename T> struct result<negate_f(T const&)> // exact argument_type of negate<T> { typedef typename negate<T>::result_type type; };
This specialization says that negate_f can only accept const lvalues.
template <typename T> typename result<negate_f(T const&)>::type operator()(T const& x) const { return negate<T>()(x); } };
// generic apply function // do we pass by value or const reference here? template <typename Func, typename T> typename boost::result_of<Func(T)>::type
This says that you ask for type of the return value of F when passed an rvalue of type T.
apply(Func f, T x) { return f(x);
But you pass an lvalue of type T here.
}
int main() { apply(negate_f(), 5); }
Try this variation instead: #include <boost/utility/result_of.hpp> #include <boost/type_traits/remove_const.hpp> #include <boost/type_traits/remove_reference.hpp> struct negate; namespace boost { template<class T> struct result_of<negate(T)> { typedef typename remove_reference<T>::type no_ref; typedef typename remove_const<no_ref>::type type; }; } // boost struct negate { template<class T> T operator()(T const & x) const { return -x; } }; template <typename Func, typename T> typename boost::result_of<Func(T&)>::type apply(Func f, T x) { return f(x); } int f( int x ) { return -x; } int main() { apply( f, 5 ); apply( negate(), 5 ); }