Boost logo

Boost :

Subject: Re: [boost] [contract] concepts: pseudo-signatures vs. usage patterns
From: Doug Gregor (doug.gregor_at_[hidden])
Date: 2012-10-11 16:41:29


On Thu, Oct 11, 2012 at 7:09 AM, Andrew Sutton <asutton.list_at_[hidden]> wrote:
>> Next, for OutputIterator, I want operation (*it = v) to be valid. But I
>> never intend to use the assignment alone or the indirection alone. With
>> usage-patterns, I can write:
>>
>> *it = v; // cannot use the result of the assignment
>>
>> With pseudo signatures, I need to specify at least two declarations, and I
>> need to specify what the operator* returns, even though it should be an
>> implementation detail:
>>
>> typename DerefResult;
>> DerefResult operator*(Iter&);
>> void operator=(DerefResult, ValueType<Iter>);
>>
>> But again, maybe this operation should be output(it, v), and it is STL's
>> limitation that it uses a combination of operators for a sort-of 'atomic'
>> operation.
>
> Neither pro nor con, and I'm not sure if this will add anything to the
> debate, but Marcin and I had a long discussion, as we were writing the
> TR about requirements involving compound expressions. I think we ended
> up with the idea that you can always split a compound expression into
> sub-expressions using auto and &&.
>
> auto&& r = *i;
> r = x;
>
> I believe that this would essentially equivalent to what would be
> declared using pseudo-signatures. That is, an unspecified, deduced
> type name whose only requirement was to support assignment.

This rough equivalence has been known and understood since the initial
concepts proposals were discussed. There are some fiddly details with
parameter passing: is it "as if" we're passing by lvalue reference?
const lvalue reference? rvalue reference? Pseudo-signatures make these
details explicit, but usage patterns have always been underspecified
in this regard.

Back to the intermediate type of *i... with pseudo-signatures, you
need to name this intermediate type, while usage patterns allow the
type to remain anonymous. I think there is significant value in having
to name this intermediate type: for one, the compiler can use this
type in error messages that occur while type-checking constrained
templates, rather than having to spew out something like
'decltype(*i)' or 'the type of the expression *i". Moreover, giving
the type a name helps both the concept author and the concept user
understand the role of this intermediate type. I find it instructive
that, even in the original, usage-pattern-based description of the
STL, the intermediate types are still called out and given names (the
result of *i is the reference type).

  - Doug


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