C++ Logo

std-proposals

Advanced search

Re: [std-proposals] p3039r1 proxy temporary objects

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Fri, 20 Feb 2026 23:32:22 +0100
pt., 20 lut 2026 o 20:46 Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]> napisał(a):
>
> On Fri, Feb 20, 2026 at 1:39 PM Marcin Jaczewski via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> Paper suggests rewriting `ptr->meber` by `(*ptr).member`.
>>
>> But this creates an interesting case, new `->` created this way will
>> have capabilities impossible compared to manually written `->`.
>
>
> Yes, and P3039R1 mentions that it does, in §6:
>
>> Simply removing the operator-> definition from classes could possibly cause a different member function to be invoked. Specifically if the operator* that is chosen returns an rvalue reference and we are invoking a member function that has been both lvalue and rvalue reference qualified: using operator-> would cause the lvalue qualified form to be invoked but using operator* would cause the rvalue qualified form to be invoked. This may cause subtle behaviour changes.
>
>
> However, I do see that §6.4 erroneously lists `optional` as one of the types that "have an operator-> that is identical to what the rewrite would accomplish." In fact, `optional` is one of the poster-child types that are intended to become more powerful with the rewrite.
>
> // https://godbolt.org/z/ah5jEjsvP
>
> optional<S> f();
>
> void use(int&); // #1
> void use(int&&); // #2
>
> int main() {
> use(f()->m); // calls #1; P3039 will change this to call #2
> use((*f()).m); // calls #2
> }
>
> Actually, the reference implementation on Godbolt gets this example wrong, so maybe this effect was unintended too (although I'm not sure how to square that with the quotation from §6, which seems to indicate that the authors were very much aware of this effect).
>

As far as I know it works fine, the only problem is that you have
defined `operator->` that blocks this overwrite, when commented out,
it breaks current Clang but makes new one call #2 in both cases.

https://godbolt.org/z/v951hfGr6

>> Consider example:
>> ```
>> const auto& foo = ptr->member;
>> ```
>> and `ptr` that has a `*` returning proxy value.
>> With this rewrite, the lifetime of the proxy object will be expanded
>> to the lifetime of the `foo` reference.
>
>
> Yes, that's another good example.
>
>> maybe we should discourage of further use of user defined `->` operator?
>
>
> Informally, yes, of course. P3039's adding rewrite rules for `->` is exactly analogous to how C++20 added rewrite rules for `!=`. It doesn't mean that defining your own `operator!=` is somehow morally bad at this point, but it does mean that we expect defining your own `operator!=` to become much rarer, and certainly unidiomatic in modern C++. However, because of the billions of lines of code out there that do define their own `operator!=`, it wouldn't be sensible to try to "push" anyone off of it (e.g. by deprecating the syntax or anything like that). We can afford to let the newer cleaner style displace the older more verbose style in its own natural time.
>
> –Arthur

Received on 2026-02-20 22:32:35