Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2008-04-07 14:14:14


Giovanni Piero Deretta wrote:
> On Mon, Apr 7, 2008 at 6:19 PM, Daniel Walker <daniel.j.walker_at_[hidden]> wrote:
>> On Mon, Apr 7, 2008 at 11:37 AM, Eric Niebler <eric_at_[hidden]> wrote:
>> > And is there a plan in C++0x
>> > to require std::result_of to be implemented in terms of decltype?
>>
>> Yes. There was a proposal to remove the result_type/result<> heuristic
>> described in TR1 3.4/3 entirely since implementers can just use
>> decltype.
>>
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2194.pdf
>>
>> I'm not sure if that's been accepted by the committee yet or not.
>>
>
> The last draft standard (n2588) has no mention of the result<...> protocol:
> The definition of result_of simply states:
>
> namespace std {
> // undefined
> template <class> class result_of;
>
> template <class Fn, class... ArgTypes>
> class result_of<Fn(ArgTypes...)> {
> public :
> // types
> typedef see below type;
> };
> }
> Given an rvalue fn of type Fn and values t1, t2, ..., tN of types
> T1, T2, ..., TN in ArgTypes, respectively,
> the type member is the result type of the expression fn(t1, t2,
> ...,tN). The values ti are lvalues when the
> corresponding type Ti is a reference type, and rvalues otherwise.
>
> So, yes, the result<> seems to be gone.

Thanks Giovanni. So these are all valid:

std::result_of<F(int)>::type
std::result_of<F(int &)>::type
std::result_of<F(int const &)>::type

And they all mean different things. Now perhaps you can see that in
C++03 we have a problem because F::result<> has more information (the
rvalue/lvalue-ness of the arguments) than F::operator() has. This is
precisely the point I've been trying to make.

Basically, I see the notion of a polymorphic function object in C++03 to
be fundamentally flawed. I'm giving up trying to use result_of in proto
transforms because it simply cannot be made to work.

In MPL there is the notion of a metafunction and a distinct notion of a
metafunction class:

// a metafunction
template<typename T>
struct metafun
{ typedef ... type; };

// a metafunction class
struct metafun_class
{
   template<typename T>
   struct apply
   {
     typedef ... type;
   };
};

What I'm saying is that, in C++03, polymorphic function objects are
broken, so we need the runtime equivalent of a metafunction class ... a
generator for monomorphic function objects. Call it a function class:

struct fun_class
{
   template<typename A>
   struct apply
   {
     typedef ... result_type;
     result_type operator()(
         typedef add_const_ref<A>::type a
     ) const
     {
       return ...;
     }
   };
};

Now both the return type calculation *and* the operator() have access to
*all* the information about the arguments, even their lvalue/rvalue-ness.

-- 
Eric Niebler
Boost Consulting
www.boost-consulting.com

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