C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Why [expr.ref] says that E1->E2 is converted to (*(E1)).E2

From: Sean Mayard <seanmayard_at_[hidden]>
Date: Tue, 9 May 2023 21:55:21 +0530
@jonathan

[expr.pre] also says *Overloaded operators obey the rules for syntax and
evaluation order specified in* [expr.compound]
<https://timsong-cpp.github.io/cppwp/n4868/expr.compound>...

So even though [expr.compound] is for built in types, [expr.compound] also
applies to overloaded operators?

On Tue, 9 May 2023, 21:36 Jonathan Wakely, <cxx_at_[hidden]> wrote:

>
>
> On Tue, 9 May 2023 at 15:42, Sean Mayard <seanmayard_at_[hidden]> wrote:
>
>> Look at the previous sentence.
>>
>>
>> Okay, so the previous sentence says "For the first option (dot) the first
>> expression shall be a glvalue.
>> <https://timsong-cpp.github.io/cppwp/n4868/expr.ref#2.sentence-1> For
>> the second option (arrow) the first expression shall be a prvalue having *pointer
>> type*. <https://timsong-cpp.github.io/cppwp/n4868/expr.ref#2.sentence-2>
>> " By pointer type they mean built-in pointer type and not smart pointer
>> type.
>>
>
> Yes, smart pointers have class type. There are no "smart pointer types" in
> the type taxonomy of C++, that's just an idiomatic name for class types
> with a pointer-like API.
>
> But it's irrelevant, [expr.pre] means the whole paragraph only applies to
> the built-in operator, not an overloaded operator. There are no built-in ->
> operators for smart pointer types, only operator->() overloads.
>
>
>
>
>> On Tue, 9 May 2023 at 18:35, Jonathan Wakely <cxx_at_[hidden]> wrote:
>>
>>>
>>>
>>> On Tue, 9 May 2023 at 13:10, Sean Mayard via Std-Proposals <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>>> I read [expr.ref#2] which includes the following sentence:
>>>>
>>>> > *The expression E1->E2 is converted to the equivalent form
>>>> (*(E1)).E2*
>>>>
>>>> My question is, does this mean that "every" expression that has the
>>>> form *E1->E2* will be converted to *(*(E1)).E2. *I mean it is not
>>>> clear to me in what situations/contexts does the above sentence hold?
>>>>
>>>> For example, suppose we have a class that overloads *operator* *but
>>>> does not overload *operator->* then if we use *operator-> *with an
>>>> object of that class type, then that expression will be first converted to
>>>> *(*(E1)).E2* form?
>>>>
>>>> #include <iostream> struct A { int foo = 1, bar =2;};struct B { A a{}; A& operator* () { return a; }}; int main(){ B b{}; int x = b->foo; //i know this will give error because there is no overloaded operator-> //but according to [expr.ref#2] shouldn't b->foo be first converted to (*(b)).foo //and then the overloaded operator* should be used }
>>>>
>>>>
>>>> As you can see in the above program, `b->foo;` gives an error because
>>>> the class `B` has not overloaded *operator-> *. But according to
>>>> [expr.ref#2] the expression *b->foo *should be converted to *(*(b)).foo
>>>> *and then the *operator* *could be used.
>>>>
>>>> So I want to know what exactly does [expr.ref#2] mean when it said " *The
>>>> expression E1->E2 is converted to the equivalent form (*(E1)).E2* ".
>>>> Does this conversion supposed to happen only after `E1->E2` is valid or
>>>> before. Is a CWG issue required for this or I just did not read/interpret
>>>> it correctly.
>>>>
>>>
>>> See [expr.pre] which explains that the rules in Clause [expr] apply to
>>> the built-in operators, not to overloaded operators.
>>>
>>> "Subclause 7.6 defines the effects of operators when applied to types
>>> for which they have not been overloaded." (and also the note before that).
>>>
>>>
>>>

Received on 2023-05-09 16:25:35