Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2008-04-05 18:00:08


Eric Niebler:

> I clearly should have fleshed this out a bit more. Consider something
> like a fusion::make_tuple function object
>
> struct make_tuple
> {
> template<typename Sig> struct result;
>
> template<typename This, typename Arg>
> struct result< This( Arg ) >
> {
> typedef tuple< Arg > type;
> };
>
> // This is wrong!
> template<typename Arg>
> typename result< make_tuple( Arg const & ) >::type
> operator ()( Arg const &arg )
> {
> return tuple< Arg const & >( arg );
> }
> };
>
>
> This is wrong because make_tuple(1) will cause the resulting tuple to
> hold on to a dangling reference. But had it been called as:
>
> int const i = 0;
> make_tuple( i );
>
> ... then it's correct.

Yes. It's also wrong because result_of<make_tuple(int&)>::type says
tuple<int&>, but the result of make_tuple( i ) is actually tuple<int
const&>. But this is not a problem with result_of. It's not supposed to be
used in this self-referential way. result_of<F(X)>::type is nothing more
than an alias of decltype(f(x)), where f and x have types F and X,
respectively. So if you have:

    return f(x);

you can write

    template<class X> typename result_of<F(X const&)>::type g( X const & x )
    {
        return f(x);
    }

You don't use result_of<G(X)> in the return type of g(x). This would be the
equivalent of using decltype(g(x)) as the return type of g.

If you write the actual make_tuple:

struct make_tuple
{
    template<class X> tuple<X> operator()( X const & x ) const
    {
        return tuple<X>( x );
    }

    template<class X> tuple<X&>
    operator()( reference_wrapper<X> const & x ) const
    {
        return tuple<X&>( x.get() );
    }
};

you'll see that it's relatively easy to write a result_of specialization for
it. The references are an annoyance, sure. But the idea is that you start
with the function object and then derive its result_of, not vice versa.

Maybe I'm missing something else.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk