On Fri, Feb 28, 2020 at 8:42 PM Hubert Tong <hubert.reinterpretcast@gmail.com> wrote:
On Fri, Feb 28, 2020 at 10:25 PM J Decker via Liaison <liaison@lists.isocpp.org> wrote:


On Fri, Feb 28, 2020 at 10:07 AM Patrice Roy via Liaison <liaison@lists.isocpp.org> wrote:
My initial point in response to your message was to point out that in C++, there are cases where making '.' behave as '->' does today breaks otherwise correct code and introduces ambiguity.

C++ users, contrary to C# or Java users, have the option of using objects directly or indirectly. In C# (excluding structs) and Java, all objects are accessed through indirect means. On the other hand, for a C++ programmer using a smart pointer such as unique_ptr<T>, the ability to distinguish the services exposed by that object (using '.') and those exposed by the pointee (using '->') carries meaning, and that distinction is not readily accessible in some other languages this proposal refers to.

Please also note that operator-> can be (and is sometimes) overloaded in C++ classes.


I'm failing to communicate 'where it is now an error'.
I think the clarification needs to go beyond that. Using . on a class instance where the name to the right does not clearly name a specific member is also an error.



I was looking at the C++17 standard...

6.4.5 defines 'class member access' about how the id on the right of -> and . is looked up... 

8.5.1.5 2)
       For the first option (dot) the first expression shall be a glvalue having class type.
      For the second option (arrow) the first expression shall be a prvalue having pointer to class type  
     `E1->E2 is converted to the equivalent form (*(E1)).E2;`
     `  the remainder of 8.5.1.5 will address only the first option (dot).`  ...

So what exactly makes the '.' on a 'pointer to class type' generate an error?  
Not having 'class type' but having 'pointer to class type' type?  

Pointers, as declared with '*' or created with (&) or as the conversion of a function or array results in, is just a 'pointer to a ...' , and this sort of pointer do not have members/properties to access. 

There's 3 ways a pointer to a class (not scalar, '.' operator doesn't apply on pointers to scalar types either) can be used `(*ptr)._id_ `, `ptr[n]. _id_ `, and `ptr->_id_`; the last is converted to the first, array accesses are also converted to (*(ptr+n))._id_ which leads to '.' as the primary operator...  one operator that cannot, right now, apply to a pointer to a class is '.' .

I suppose the suggested change would be

if the first expression of (dot) is a pointer, then E1.E2 is converted to (*(E1)).E2 .

Although I see the potential recursion there 

class X ****x;   `x.property` could be `(*(*(*(*(x)))).property`
and unique_ptr<X> ***upx;    `upx.reset();` could be (*(*(*(upx)))).reset() and still work...

Maybe reword the above specifying that 'pointer to pointer to...' is still an invalid type to '.' and only one level of pointer indirection may apply.  ( ' The unary * operator performs indirection:' )



--- other standards sections ...

23.11 Smart Pointers
     .1 1)  `A unique pointer is an object that owns another object and manages that other object through a pointer. More precisely, a unique pointer is an object u that stores a pointer to a second object p`...

So, a Smart pointer is an object, not a pointer to an object; but clearly 'is an object that owns [a pointer to] another object].
where did 'object' get defined to relate to 'class type' or 'pointer to class type'....

6.6.1 Memory Model 
   3)  "A memory location is either an object of scalar type or a maximal sequence of adjacent bit-fields all having nonzero width "

6.7.2 Compound Types 3)  ...' A pointer to objects of type T is referred to as a “pointer to T '...




  6.4.5 Class member access [basic.lookup.classref] 
"1 In a class member access expression (8.5.1.5), if the . or -> token is immediately followed by an identifier followed by a <, the identifier must be looked up to determine whether the < is the beginning of a template argument list (17.2) or a less-than operator. The identifier is first looked up in the class of the object expression. If the identifier is not found, it is then looked up in the context of the entire postfix-expression and shall name a class template.   "