Boost logo

Boost Users :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2005-03-16 13:45:14


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 );
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net