C++ Logo

std-discussion

Advanced search

Re: Access level for defaulted comparison operators

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Wed, 24 Nov 2021 23:59:45 +0000
Hi,

On Wed, 24 Nov 2021 13:34:50 -0500
Jason McKesson via Std-Discussion <std-discussion_at_[hidden]>
wrote:

> On Wed, Nov 24, 2021 at 10:21 AM Richard Hazlewood via Std-Discussion
> <std-discussion_at_[hidden]> wrote:
> >
> > Hi,
> >
> > I was recently going through a refactoring exercise to make use of
> > default comparison operators.
> >
> > For some hierarchical classes I was concerned about the slicing
> > problem, so thought no problem I'll just make the base operator
> > protected.
> >
> > However, this fails to compile (with gcc 10 & 11, -std=c++20). It
> > appears that the base operator is inaccessible.
>
> ... yes. That's what you *asked* for when you made it protected. You
> stated that code outside of the derived hierarchy of classes
> You> cannot
> call it.
>
> This includes `main`.

I don't think the question was aimed at the commented out code. For
some reason the base operator seem to be inaccessible even within D,
when operator== is defaulted there.

https://godbolt.org/z/sxaW5GWTn

The problem seem to stem from that the defaulted operator== is defined
in terms of (lhs_i == rhs_i && ...) for each subobject. But you can't
call a protected member function on only arguments of base type.
Writing the operator== manually in the equivalent way fails too:

https://godbolt.org/z/Evcf6K8Yv

Manually it can be worked around like this:

https://godbolt.org/z/b4oz5T6h9

I think it's an interesting collision of how defaulted special member
functions are defined and a protection mechanism of protected member
functions.

However defaulted assignment doesn't seem to suffer from this problem,
 although the situation is similar:

https://godbolt.org/z/v4xExP5W1 // defaulted
https://godbolt.org/z/n8EcqGov8 // trying with `this_base = other_base`
https://godbolt.org/z/cYMazTsbW // with `this->B::operator=(other)`

The standard doesn't seem to specify how the base subobjects are
assigned (via operator or the above function call notation from the
context of the derived class).

Cheers,
Lénárd

Received on 2021-11-24 18:00:00