
On Thu, Oct 11, 2012 at 7:09 AM, Andrew Sutton <asutton.list@gmail.com> 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