C++ Logo

std-proposals

Advanced search

Re: This deduction and access control

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Mon, 20 Jul 2020 22:53:05 +0200
pon., 20 lip 2020 o 22:42 Barry Revzin <barry.revzin_at_[hidden]> napisał(a):
>
>
>
> 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

That was my point, allow `g(Y{}, 3, 2)`, because what difference is to
the definition of `friend int g(Y const&, int, int);`?
Of course paper do not suggest this, but for me this is a logical
conclusion. As this is op-in we do not have problems like other
solutions had for that functionality.

Received on 2020-07-20 15:56:38