
Peter Dimov wrote:
Ian McCulloch wrote:
Peter Dimov wrote:
Ian McCulloch wrote:
Yes, if you want to forward to a function but you don't know if it takes arguments by value or const reference.
It doesn't matter. When you forward, you pass to result_of the exact types of the arguments you are supplying in the function (object) call, with a reference when the argument is an lvalue.
int x; long y; int const z; int g(); int & h();
f(x, y); // result_of<F(int&, long&)> f(1, x); // result_of<F(int, int&)> f(z, 4); // result_of<F(int const&, int)> f( g(), h() ); // result_of<F(int, int&)>
What is 'f' and how it takes its arguments in the cases above does not affect how result_of is used.
But what happens if F doesn't have an operator() overload that takes F(int const&, int) but only has F(int, int) ? It seems you need to know this in advance.
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? Otherwise I don't understand what magic incantions result_of would have to do to figure it out. In the following sample program, I have a functor that takes its argument by const reference, but the apply() function fails because it tries to pass by value: /usr/local/include/boost/utility/result_of.hpp: In instantiation of `boost::detail::get_result_of<negate_f, negate_f ()(int), false>': resultof_test.cpp:53: instantiated from `boost::detail::result_of<negate_f, negate_f ()(int)>' resultof_test.cpp:53: instantiated from `boost::result_of<negate_f ( (int)>' resultof_test.cpp:53: instantiated from here /usr/local/include/boost/utility/result_of.hpp:43: error: no type named `type' in `struct negate_f::result<negate_f ()(int)>' But if I change apply() to use pass by const-reference then it fails if I try to use it with a functor that uses pass by value. But maybe I am using result_of incorrectly. #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; }; 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 apply(Func f, T x) { return f(x); } int main() { apply(negate_f(), 5); } Cheers, Ian