C++ Logo

STD-PROPOSALS

Advanced search

Subject: Re: [std-proposals] This deduction and access control
From: Barry Revzin (barry.revzin_at_[hidden])
Date: 2020-07-20 15:42:00


On Mon, Jul 20, 2020 at 3:22 PM Marcin Jaczewski via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> pon., 20 lip 2020 o 21:54 Matthew Woehlke via Std-Proposals
> <std-proposals_at_[hidden]> napisał(a):
> >
> > On 20/07/2020 08.43, Magnus Fromreide via Std-Proposals wrote:
> > > When calling a deduced this member
> > >
> > > instance.deduced_this_member(a, b);
> > >
> > > then that is interpreted as
> > >
> > > deduced_this_member(instance, a, b);
> > >
> > > This looks exactly like what N4165 proposed albeit restricted to only
> > > deduced this members and that is why I asked. It could very well be
> that
> > > limiting it to only deduced this members solves all the problems.
> >
> > Er... yes and no. The difference is, what you wrote is how C++ has
> > *always* worked, with the caveat that you don't "see" the 'instance'
> > argument in a member function (except as `this`).
> >
> > The difference you are possibly overlooking is that
> > `deduced_this_member` is still a *member* function, with all the
> > limitations and other attributes thereof. UFCS is about being able to
> > substitute *free* functions. P0847, OTOH, is just making the previously
> > implicit `this` argument more exposed (a bit like Python), with
> > additional fiddly-bits to make said exposure more useful.
> >
> > Really, though, it's that "still a member function" that's important. A
> > lot of the issues with UFCS deal with knowing whether you're calling a
> > member or a free function, and the ability to arbitrarily introduce
> > matching free functions. So, yes, "limiting it to only deduced this
> > members solves all the problems" is probably (at least mostly) accurate.
> >
>
> No, this functions are not member functions, you can't use them as
> member functions because of case like `void f(this T);` what member
> function pointer type is this?
>

Yes, these functions are member functions and you can use them as member
functions. The type of f here, assuming it's in the middle of a class
(otherwise it would be ill-formed), is void(*)(T). In the same way that the
type of a pointer to a static member function is also a pointer to function.

They're basically a hybrid between static and non-static member functions -
static in the sense of the type and the lack of implicit this, and
non-static in the sense of how invocation works.

>
> p0847r4:
> >>
> >> struct Y {
> >> int f(int, int) const&;
> >> int g(this Y const&, int, int);
> >> };
> >> While the type of &Y::f is int(Y::*)(int, int) const&, the type of
> &Y::g is int(*)(Y const&, int, int).
> >> As these are just function pointers, the usage of these two member
> functions differs once we drop them to pointers:
>
> This means we can drop last pretend and allow both call conventions.
>

If by "both call conventions", you mean to also Y::g(Y{}, 1, 2), then yes
that already is valid as stated in the paper (because they're like static
member functions) in the same way that Y{}.g(1, 2) is valid (because
they're like non-static member functions).

If what you mean is to allow g(Y{}, 1, 2), then... no.

Barry



STD-PROPOSALS list run by herb.sutter at gmail.com

Standard Proposals Archives on Google Groups