C++ Logo

std-discussion

Advanced search

Re: Fw: The unnecessary confusion of the C++23 proposal P0847R6

From: Barry Revzin <barry.revzin_at_[hidden]>
Date: Tue, 3 Aug 2021 19:05:02 -0500
On Mon, Aug 2, 2021 at 8:34 PM Jason McKesson via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> On Mon, Aug 2, 2021 at 7:41 PM Hani Deek via Std-Discussion
> <std-discussion_at_[hidden]> wrote:
> >
> > The non-static member functions which we have now do not accept the
> 'implicit object argument' by value. It has to be passed by reference. If
> the proposal will simply introduce a new syntax to define that kind of
> functions, then the proposed syntax shouldn't allow the object parameter to
> be non-reference. If you do that, you should not run into any kind of
> problems with regard to the type of the function pointer.
>
> OK, so let's look at this.
>
> You want to discard literally every use case of this feature *except*
> deduplication of `const` or other qualified parameters. You want a
> feature focused specifically on just that. It's still going to have to
> use templates to generate the various overloads, but you want it to
> only work in that use case. So we give up recursive lambdas, better
> CRTP, by-value members, SFINAE-friendly callables.
>
> And in exchange, we get...
>
> What?
>
> Tell me. We get what? Fewer pages in the standard? In a standard that
> already has eighteen *hundred* pages, we would have... *two* fewer
> pages.
>
> Because if what you care about is standard "complexity", it's *really*
> just that. Go look at the current wording in P0847. It's incredibly
> *short*. Most of its changes are turning "non-static member function"
> into "implicit object function", a mere text replacement. There are a
> couple of big blocks of text, but none of these are more than a single
> page.
>
> Also note that in this wording, explicit object functions are
> considered non-static even though their function pointers are not
> member pointers.
>

I'd like to second basically all of that.

Your proposal here is, basically, to add a restriction onto the object
parameter of an explicit object member function such that it must be some
kind of reference to the class type. But, why that restriction? We don't
typically have restrictions on function parameter types. There's only one I
can think of, and that's:

struct C {
    C(C); // can't do this
};

That's rejected because it makes zero sense to allow. That's a pretty
reasonable restriction. Other restrictions we have are like... operator[]
can only take a single parameter (possibly soon to be loosened) and not
being able to have parameters after a parameter pack (proposal in flight,
but this case does add complexity to overload resolution).

But in this context, adding a restriction to the explicit object parameter
is a very unique kind of restriction in that we wouldn't be preventing any
harm or avoiding complexity in other rules. Allowing a value parameter just
falls out of the fact that it's a parameter. Restricting it to be a
reference is complexity in its own right.

Additionally, in order to truly have member function type, you may have to
reject cases like this:

struct B {
    template <typename Self> void f(this Self&&);
};
struct D : B { };
D().f();

Can the type of &B::f<D> really be a void(D::*)()? I don't actually know.
It's certainly not obvious whether or not this would work.

The nice thing about the proposal as-is is that it's really actually quite
small as far as language diff goes (as Jason pointed out), all the rules
and behaviors just fall out of other rules and behaviors. The explicit
object parameter is just a function parameter and has the same rules as
other function parameters, and then explicit object member functions behave
just like other functions. That's pretty nice.

The only possible benefit I see of restricting to reference types would be
allowing virtual functions:

struct B {
    virtual void f(this B&); // ill-formed in the proposal
};

The paper goes into why virtual functions are problematic here, and this
would alleviate those problems (by way of alleviating lots of other
benefits), but that trade off doesn't seem worthwhile - since allowing you
to write virtual functions this way doesn't let you do anything that you
couldn't do before.

Barry

Received on 2021-08-03 19:05:20