Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Default comparisons(since C++20)

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
      Expressions
      General
      Literals
      Operators
      Conversions
       

      Comparison operator functions can be explicitly defaulted to request the compiler to generate the corresponding default comparison for a class.

      Contents

      [edit]Definition

      Adefaulted comparison operator function is a non-template comparison operator function (i.e.<=>,==,!=,<,>,<=, or>=) satisfying all following conditions:

      Such a comparison operator function is termed adefaulted comparison operator function for classC.

      struct X{bool operator==(const X&)const=default;// OKbool operator==(const X&)=default;// Error: the implicit object//        parameter type is X&bool operator==(this X, X)=default;// OK}; struct Y{friendbool operator==(Y, Y)=default;// OKfriendbool operator==(Y,const Y&)=default;// Error: different parameter types}; bool operator==(const Y&,const Y&)=default;// Error: not a friend of Y

      Name lookups and access checks in the implicit definition of a comparison operator function are performed from a context equivalent to its function body. A definition of a comparison operator function as defaulted that appears in a class must be the first declaration of that function.

      [edit]Default comparison order

      Given a classC, a subobject list is formed by the following subjects in order:

      • The direct base class subobjects ofC, in declaration order.
      • The non-staticdata members ofC, in declaration order.
      • If any member subobject is of array type, it is expanded to the sequence of its elements, in the order of increasing subscript. The expansion is recursive: array elements of array types will be expanded again until there is no subobject of array type.

      For any objectx of typeC, in the following descriptions:

      struct S{}; struct T: S{int arr[2][2];} t; // The subobject list for “t” consists of the following 5 subobjects in order:// (S)t → t[0][0] → t[0][1] → t[1][0] → t[1][1]

      [edit]Three-way comparison

      Anoperator<=> for a class type can be defined as defaulted with any return type.

      [edit]Comparison category types

      There are three comparison category types:

      Type Equivalent values are..  Incomparable values are.. 
      std::strong_orderingindistinguishablenot allowed
      std::weak_orderingdistinguishablenot allowed
       std::partial_ordering distinguishableallowed

      [edit]Synthesized three-way comparison

      Thesynthesized three-way comparison of typeT between glvaluesa andb of the same type is defined as follows:

      • If the overload resolution fora<=> b results in a usable candidate, and can be explicitly converted toT usingstatic_cast, the synthesized comparison isstatic_cast<T>(a<=> b).
      • Otherwise, if any of the following condition is satisfied, the synthesized comparison is not defined:
      • The overload resolution fora<=> b finds at least one viable candidate.
      • T is not a comparison category type.
      • The overload resolution fora== b does not result in a usable candidate.
      • The overload resolution fora< b does not result in a usable candidate.
      a== b? std::strong_ordering::equal:a< b? std::strong_ordering::less:         std::strong_ordering::greater
      a== b? std::weak_ordering::equivalent:a< b? std::weak_ordering::less:         std::weak_ordering::greater
      a== b? std::partial_ordering::equivalent:a< b? std::partial_ordering::less:b< a? std::partial_ordering::greater:          std::partial_ordering::unordered

      [edit]Placeholder return type

      If the declared return type of a defaulted three-way comparison operator function (operator<=>) for a class typeC isauto, the return type is deduced from the return types of the three-way comparisons between the corresponding subobjects of an objectx of typeC.

      For each subobjectx_i in the(expanded) subobject list forx:

      1. Perform overload resolution forx_i<=> x_i, if the overload resolution does not result in a usable candidate, the defaultedoperator<=> is defined as deleted.
      2. Denote the cv-unqualified version of the type ofx_i<=> x_i asR_i, ifR_i is not a comparison category type, the defaultedoperator<=> is defined as deleted.

      If the defaultedoperator<=> is not defined as deleted, its return type is deduced asstd::common_comparison_category_t<R_1, R_2, ..., R_n>.

      [edit]Non-placeholder return type

      If the declared return type of the defaultedoperator<=> is notauto, it cannot contain anyplaceholder type (e.g.decltype(auto)).

      If there is a subobjectx_i in the (expanded) subobject list forx such that thesynthesized three-way comparison of the declared return type betweenx_i andx_i is not defined, the defaultedoperator<=> is defined as deleted.

      [edit]Comparison result

      Letx andy be the parameters of a defaultedoperator<=>, denote each subobject in the (expanded) subobject list forx andy asx_i andy_i respectively. The default three-way comparison betweenx andy is performed by comparing corresponding subobjectsx_i andy_i with increasingi order.

      LetR be the (possibly-deduced) return type, the comparison result betweenx_i andy_i is the result of the synthesized three-way comparison of typeR betweenx_i andy_i.

      • During the default three-way comparison betweenx andy, if a subobject-wise comparison betweenx_i andy_i generates a resultv_i such that contextually convertingv_i!=0 tobool yieldstrue, the return value is a copy ofv_i (the remaining subobjects will not be compared).
      • Otherwise, the return value isstatic_cast<R>(std::strong_ordering::equal).
      Run this code
      #include <compare>#include <iostream>#include <set> struct Point{int x;int y;auto operator<=>(const Point&)const=default;/* non-comparison functions */}; int main(){    Point pt1{1,1}, pt2{1,2};std::set<Point> s;// OK    s.insert(pt1);// OK // two-way comparison operator functions are not required to be explicitly defined:// operator== is implicitly declared (see below)// the overload resolutions of other candidates will select rewritten candidatesstd::cout<<std::boolalpha<<(pt1== pt2)<<' '// false<<(pt1!= pt2)<<' '// true<<(pt1<  pt2)<<' '// true<<(pt1<= pt2)<<' '// true<<(pt1>  pt2)<<' '// false<<(pt1>= pt2)<<' ';// false}

      [edit]Equality comparison

      [edit]Explicit declaration

      Anoperator== for a class type can be defined as defaulted with return typebool.

      Given a classC and an objectx of typeC, if there is a subobjectx_i in the (expanded) subobject list forx such that the overload resolution forx_i== x_i does not result in a usable candidate, the defaultedoperator== is defined as deleted.

      Letx andy be the parameters of a defaultedoperator==, denote each subobject in the (expanded) subobject list forx andy asx_i andy_i respectively. The default equality comparison betweenx andy is performed by comparing corresponding subobjectsx_i andy_i with increasingi order.

      The comparison result betweenx_i andy_i is the result ofx_i== y_i.

      • During the default equality comparison betweenx andy, if a subobject-wise comparison betweenx_i andy_i generates a resultv_i such that contextually convertingv_i tobool yieldsfalse, the return value isfalse (the remaining subobjects will not be compared).
      • Otherwise, the return value istrue.
      Run this code
      #include <iostream> struct Point{int x;int y;bool operator==(const Point&)const=default;/* non-comparison functions */}; int main(){    Point pt1{3,5}, pt2{2,5};std::cout<<std::boolalpha<<(pt1!= pt2)<<'\n'// true<<(pt1== pt1)<<'\n';// true struct[[maybe_unused]]{int x{}, y{};} p, q;// if (p == q) {} // Error: operator== is not defined}

      [edit]Implicit declaration

      If a classC does not explicitly declare any member or friend namedoperator==, an== operator function is declared implicitly for eachoperator<=> defined as defaulted. Each implicity-declaredoperator== have the same access andfunction definition and in the sameclass scope as the respective defaultedoperator<=>, with the following changes:

      template<typename T>struct X{friendconstexprstd::partial_ordering operator<=>(X, X)        requires(sizeof(T)!=1)=default;// implicitly declares: friend constexpr bool operator==(X, X)//                          requires (sizeof(T) != 1) = default; [[nodiscard]]virtualstd::strong_ordering operator<=>(const X&)const=default;// implicitly declares: [[nodiscard]] virtual bool//                          operator==(const X&) const = default;};

      [edit]Secondary comparison

      A secondary comparison operator function (!=,<,>,<=, or>=) for a class type can be defined as defaulted with return typebool.

      Let@ be one of the five secondary comparison operators, for each defaultedoperator@ with parametersx andy, up to two overloads resolutions are performed (not considering the defaultedoperator@ as a candidate) to determine whether it is defined as deleted.

      • The first overload resolution is performed forx @ y. If the overload resolution does not result in a usable candidate, or the selected candidate is not arewritten candidate, the defaultedoperator@ is defined as deleted. There is no second overload resolution in these cases.
      • The second overload resolution is performed for the selected rewritten candidate ofx @ y. If the overload resolution does not result in a usable candidate, the defaultedoperator@ is defined as deleted.

      If isx @ y cannot be implicitly converted tobool, the defaultedoperator@ is defined as deleted.

      If the defaultedoperator@ is not defined as deleted, it yieldsx @ y.

      struct HasNoRelational{}; struct C{friend HasNoRelational operator<=>(const C&,const C&);bool operator<(const C&)const=default;// OK, function is defaulted};

      [edit]Keywords

      default

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 2539C++20the synthesized three-way comparison would choose
      static_cast even if the explicit conversion is not available
      does not choose
      static_cast in this case
      CWG 2546C++20the defaulted secondaryoperator@ was not
      defined as deleted if the overload resolution of
      x @ y selects a non-usable rewritten candidate
      defined as deleted
      in this case
      CWG 2547C++20it was unclear whether comparison operator
      functions for non-classes can be defaulted
      they cannot be defaulted
      CWG 2568C++20the implicit definition of comparison operator
      functions might violate member access rules
      access checks are performed
      from a context equivalent
      to their function bodies

      [edit]See also

      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/default_comparisons&oldid=183349"

      [8]ページ先頭

      ©2009-2025 Movatter.jp