Date: Fri, 20 Feb 2026 14:46:04 -0500
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
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3039r1.pdf>
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).
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
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
<https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2026/p3039r1.pdf>
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).
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 19:46:20
