|
6642 | 6642 | declared in the \grammarterm{member-specification} of \tcode{C}
|
6643 | 6643 | that is
|
6644 | 6644 | \begin{itemize}
|
6645 |
| -\item a non-static member of \tcode{C} having one parameter of type \tcode{const C\&}, or |
| 6645 | +\item a non-static const member of \tcode{C} having one parameter of type \tcode{const C\&}, or |
6646 | 6646 | \item a friend of \tcode{C} having two parameters of type \tcode{const C\&}.
|
6647 | 6647 | \end{itemize}
|
6648 | 6648 |
|
6649 | 6649 | \pnum
|
6650 |
| -\indextext{structural comparison operator|see{operator, structural comparison}}% |
6651 |
| -A three-way comparison operator for a class type \tcode{C} |
6652 |
| -is a \defnadj{structural comparison}{operator} |
6653 |
| -if it is defined as defaulted in the definition of \tcode{C}, |
6654 |
| -and all three-way comparison operators it invokes |
6655 |
| -are structural comparison operators. |
6656 |
| -\indextext{strong structural equality|see{equality, strong structural}}% |
6657 |
| -A type \tcode{T} |
6658 |
| -has \defnadj{strong structural}{equality} |
6659 |
| -if, for a glvalue \tcode{x} of type \tcode{const T}, |
6660 |
| -\tcode{x <=> x} is a valid expression |
6661 |
| -of type \tcode{std::strong_ordering} or \tcode{std::strong_equality} |
6662 |
| -and either does not invoke a three-way comparison operator |
6663 |
| -or invokes a structural comparison operator. |
| 6650 | +If the class definition |
| 6651 | +does not explicitly declare an \tcode{==} operator function, |
| 6652 | +but declares a defaulted three-way comparison operator function, |
| 6653 | +an \tcode{==} operator function is declared implicitly |
| 6654 | +with the same access as the three-way comparison operator function. |
| 6655 | +The implicitly-declared \tcode{==} operator for a class \tcode{X} |
| 6656 | +is an inline member and is defined as defaulted in the definition of \tcode{X}. |
| 6657 | +If the three-way comparison operator function |
| 6658 | +is declared as a non-static const member, |
| 6659 | +the implicitly-declared \tcode{==} operator function is a member of the form |
| 6660 | +\begin{codeblock} |
| 6661 | +bool X::operator==(const X&) const; |
| 6662 | +\end{codeblock} |
| 6663 | +Otherwise, the implicitly-declared \tcode{==} operator function is of the form |
| 6664 | +\begin{codeblock} |
| 6665 | +friend bool operator==(const X&, const X&); |
| 6666 | +\end{codeblock} |
| 6667 | +\begin{note} |
| 6668 | +Such a friend function is visible |
| 6669 | +to argument-dependent lookup\iref{basic.lookup.argdep} |
| 6670 | +only\iref{namespace.memdef}. |
| 6671 | +\end{note} |
| 6672 | +The operator is a \tcode{constexpr} function if its definition |
| 6673 | +would satisfy the requirements for a \tcode{constexpr} function. |
| 6674 | +\begin{note} |
| 6675 | +The \tcode{==} operator function is declared implicitly even if |
| 6676 | +the defaulted three-way comparison operator function is defined as deleted. |
| 6677 | +\end{note} |
6664 | 6678 |
|
6665 |
| -\rSec2[class.spaceship]{Three-way comparison} |
6666 |
| -\indextext{operator!three-way comparison!defaulted}% |
| 6679 | +\pnum |
| 6680 | +\indextext{structural comparison operator|see{operator, structural comparison}}% |
| 6681 | +A type \tcode{C} has \defnadj{strong structural}{equality} if, |
| 6682 | +given a glvalue \tcode{x} of type \tcode{const C}, either: |
| 6683 | +\begin{itemize} |
| 6684 | +\item |
| 6685 | + \tcode{C} is a non-class type and \tcode{x <=> x} is a valid expression |
| 6686 | + of type \tcode{std::strong_ordering} or \tcode{std::strong_equality}, or |
| 6687 | +\item |
| 6688 | + \tcode{C} is a class type with an \tcode{==} operator |
| 6689 | + defined as defaulted in the definition of \tcode{C}, |
| 6690 | + \tcode{x == x} is well-formed when contextually converted to \tcode{bool}, |
| 6691 | + all of \tcode{C}'s base class subobjects and non-static data members |
| 6692 | + have strong structural equality, and |
| 6693 | + \tcode{C} has no \tcode{mutable} or \tcode{volatile} subobjects. |
| 6694 | +\end{itemize} |
6667 | 6695 |
|
6668 | 6696 | \pnum
|
6669 | 6697 | The direct base class subobjects of \tcode{C},
|
|
6681 | 6709 | derived-to-base conversions\iref{over.best.ics},
|
6682 | 6710 | class member access expressions\iref{expr.ref}, and
|
6683 | 6711 | array subscript expressions\iref{expr.sub} applied to \tcode{x}.
|
6684 |
| -The type of the expression $\tcode{x}_i$ \tcode{<=>} $\tcode{x}_i$ |
6685 |
| -is denoted by $\tcode{R}_i$. |
6686 |
| -It is unspecified |
6687 |
| -whether virtual base class subobjects are compared more than once. |
| 6712 | +It is unspecified whether virtual base class subobjects |
| 6713 | +appear more than once in the expanded list of subobjects. |
| 6714 | + |
| 6715 | +\rSec2[class.eq]{Equality operators} |
| 6716 | +\indextext{operator!equality!defaulted}% |
| 6717 | +\indextext{operator!inequality!defaulted}% |
| 6718 | + |
| 6719 | +\pnum |
| 6720 | +A defaulted equality operator\iref{expr.eq} function |
| 6721 | +shall have a declared return type \tcode{bool}. |
| 6722 | + |
| 6723 | +\pnum |
| 6724 | +A defaulted \tcode{==} operator function for a class \tcode{C} |
| 6725 | +is defined as deleted |
| 6726 | +unless, for each $\tcode{x}_i$ in the expanded list of subobjects |
| 6727 | +for an object \tcode{x} of type \tcode{C}, |
| 6728 | +$\tcode{x}_i\tcode{ == }\tcode{x}_i$ is a valid expression and |
| 6729 | +contextually convertible to \tcode{bool}. |
6688 | 6730 |
|
6689 | 6731 | \pnum
|
| 6732 | +The return value \tcode{V} of a defaulted \tcode{==} operator function |
| 6733 | +with parameters \tcode{x} and \tcode{y} is determined |
| 6734 | +by comparing corresponding elements $\tcode{x}_i$ and $\tcode{y}_i$ |
| 6735 | +in the expanded lists of subobjects for \tcode{x} and \tcode{y} |
| 6736 | +until the first index $i$ |
| 6737 | +where $\tcode{x}_i\tcode{ == }\tcode{y}_i$ yields a result value which, |
| 6738 | +when contextually converted to \tcode{bool}, yields \tcode{false}. |
| 6739 | +If no such index exists, \tcode{V} is \tcode{true}. |
| 6740 | +Otherwise, \tcode{V} is \tcode{false}. |
| 6741 | + |
| 6742 | +\pnum |
| 6743 | +A defaulted \tcode{!=} operator function for a class \tcode{C} |
| 6744 | +with parameters \tcode{x} and \tcode{y} is defined as deleted if |
| 6745 | +\begin{itemize} |
| 6746 | +\item |
| 6747 | + overload resolution\iref{over.match}, as applied to \tcode{x == y} |
| 6748 | + (also considering synthesized candidates |
| 6749 | + with reversed order of parameters\iref{over.match.oper}), |
| 6750 | + results in an ambiguity or a function |
| 6751 | + that is deleted or inaccessible from the operator function, or |
| 6752 | +\item |
| 6753 | + \tcode{x == y} cannot be contextually converted to \tcode{bool}. |
| 6754 | +\end{itemize} |
| 6755 | +Otherwise, the operator function yields \tcode{(x == y) ?\ false :\ true}. |
| 6756 | + |
| 6757 | +\pnum |
| 6758 | +\begin{example} |
| 6759 | +\begin{codeblock} |
| 6760 | +struct D { |
| 6761 | + int i; |
| 6762 | + friend bool operator==(const D& x, const D& y) = default; |
| 6763 | + // OK, returns \tcode{x.i == y.i} |
| 6764 | + bool operator!=(const D& z) const = default; // OK, returns \tcode{(*this == z) ?\ false :\ true} |
| 6765 | +}; |
| 6766 | +\end{codeblock} |
| 6767 | +\end{example} |
| 6768 | + |
| 6769 | +\rSec2[class.spaceship]{Three-way comparison} |
| 6770 | +\indextext{operator!three-way comparison!defaulted}% |
| 6771 | + |
| 6772 | +\pnum |
| 6773 | +Given an expanded list of subobjects for an object \tcode{x} of type \tcode{C}, |
| 6774 | +the type of the expression $\tcode{x}_i$ \tcode{<=>} $\tcode{x}_i$ |
| 6775 | +is denoted by $\tcode{R}_i$. |
6690 | 6776 | If the declared return type
|
6691 | 6777 | of a defaulted three-way comparison operator function
|
6692 | 6778 | is \tcode{auto},
|
|
6756 | 6842 | \end{note}
|
6757 | 6843 | \end{itemize}
|
6758 | 6844 |
|
6759 |
| -\rSec2[class.rel.eq]{Other comparison operators} |
| 6845 | +\rSec2[class.rel]{Relational operators} |
6760 | 6846 | \indextext{operator!relational!defaulted}%
|
6761 |
| -\indextext{operator!equality!defaulted}% |
6762 |
| -\indextext{operator!inequality!defaulted}% |
6763 | 6847 |
|
6764 | 6848 | \pnum
|
6765 |
| -A defaulted relational\iref{expr.rel} or equality\iref{expr.eq} operator function |
| 6849 | +A defaulted relational\iref{expr.rel} operator function |
6766 | 6850 | for some operator \tcode{@}
|
6767 | 6851 | shall have a declared return type \tcode{bool}.
|
6768 | 6852 |
|
|
6796 | 6880 | \begin{codeblock}
|
6797 | 6881 | struct C {
|
6798 | 6882 | friend std::strong_equality operator<=>(const C&, const C&);
|
6799 |
| - friend bool operator==(const C&, const C&) = default; // OK, returns \tcode{x <=> y == 0} |
6800 | 6883 | bool operator<(const C&) const = default; // OK, function is deleted
|
6801 | 6884 | };
|
6802 | 6885 | \end{codeblock}
|
|
0 commit comments