From Jason Turner

[class.compare]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmptt8hh70v/{from.md → to.md} +259 -39
tmp/tmptt8hh70v/{from.md → to.md} RENAMED
@@ -3,23 +3,19 @@
3
  ### Defaulted comparison operator functions <a id="class.compare.default">[[class.compare.default]]</a>
4
 
5
  A defaulted comparison operator function [[over.binary]] for some class
6
  `C` shall be a non-template function that is
7
 
8
- - a non-static const non-volatile member of `C` having one parameter of
9
- type `const C&` and either no *ref-qualifier* or the *ref-qualifier*
10
- `&`, or
11
- - a friend of `C` having either two parameters of type `const C&` or two
12
- parameters of type `C`.
13
 
14
- A comparison operator function for class `C` that is defaulted on its
15
- first declaration and is not defined as deleted is *implicitly defined*
16
- when it is odr-used or needed for constant evaluation. Name lookups in
17
- the defaulted definition of a comparison operator function are performed
18
- from a context equivalent to its *function-body*. A definition of a
19
- comparison operator as defaulted that appears in a class shall be the
20
- first declaration of that function.
21
 
22
  A defaulted `<=>` or `==` operator function for class `C` is defined as
23
  deleted if any non-static data member of `C` is of reference type or `C`
24
  has variant members [[class.union.anon]].
25
 
@@ -28,47 +24,28 @@ A binary operator expression `a @ b` is *usable* if either
28
  - `a` or `b` is of class or enumeration type and overload resolution
29
  [[over.match]] as applied to `a @ b` results in a usable candidate, or
30
  - neither `a` nor `b` is of class or enumeration type and `a @ b` is a
31
  valid expression.
32
 
33
- A defaulted comparison function is *constexpr-compatible* if it
34
- satisfies the requirements for a constexpr function [[dcl.constexpr]]
35
- and no overload resolution performed when determining whether to delete
36
- the function results in a usable candidate that is a non-constexpr
37
- function.
38
-
39
- [*Note 1*:
40
-
41
- This includes the overload resolutions performed:
42
-
43
- - for an `operator<=>` whose return type is not `auto`, when determining
44
- whether a synthesized three-way comparison is defined,
45
- - for an `operator<=>` whose return type is `auto` or for an
46
- `operator==`, for a comparison between an element of the expanded list
47
- of subobjects and itself, or
48
- - for a secondary comparison operator `@`, for the expression `x @ y`.
49
-
50
- — *end note*]
51
-
52
  If the *member-specification* does not explicitly declare any member or
53
  friend named `operator==`, an `==` operator function is declared
54
  implicitly for each three-way comparison operator function defined as
55
  defaulted in the *member-specification*, with the same access and
56
  *function-definition* and in the same class scope as the respective
57
  three-way comparison operator function, except that the return type is
58
  replaced with `bool` and the *declarator-id* is replaced with
59
  `operator==`.
60
 
61
- [*Note 2*: Such an implicitly-declared `==` operator for a class `X` is
62
  defined as defaulted in the definition of `X` and has the same
63
  *parameter-declaration-clause* and trailing *requires-clause* as the
64
  respective three-way comparison operator. It is declared with `friend`,
65
  `virtual`, `constexpr`, or `consteval` if the three-way comparison
66
  operator function is so declared. If the three-way comparison operator
67
  function has no *noexcept-specifier*, the implicitly-declared `==`
68
  operator function has an implicit exception specification
69
- [[except.spec]] that may differ from the implicit exception
70
  specification of the three-way comparison operator
71
  function. — *end note*]
72
 
73
  [*Example 1*:
74
 
@@ -82,11 +59,11 @@ template<typename T> struct X {
82
  };
83
  ```
84
 
85
  — *end example*]
86
 
87
- [*Note 3*: The `==` operator function is declared implicitly even if
88
  the defaulted three-way comparison operator function is defined as
89
  deleted. — *end note*]
90
 
91
  The direct base class subobjects of `C`, in the order of their
92
  declaration in the *base-specifier-list* of `C`, followed by the
@@ -132,12 +109,12 @@ struct D {
132
  ### Three-way comparison <a id="class.spaceship">[[class.spaceship]]</a>
133
 
134
  The *synthesized three-way comparison* of type `R` [[cmp.categories]] of
135
  glvalues `a` and `b` of the same type is defined as follows:
136
 
137
- - If `a <=> b` is usable [[class.compare.default]],
138
- `static_cast<R>(a <=> b)`.
139
  - Otherwise, if overload resolution for `a <=> b` is performed and finds
140
  at least one viable candidate, the synthesized three-way comparison is
141
  not defined.
142
  - Otherwise, if `R` is not a comparison category type, or either the
143
  expression `a == b` or the expression `a < b` is not usable, the
@@ -160,13 +137,13 @@ glvalues `a` and `b` of the same type is defined as follows:
160
  a < b ? partial_ordering::less :
161
  b < a ? partial_ordering::greater :
162
  partial_ordering::unordered
163
  ```
164
 
165
- [*Note 1*: A synthesized three-way comparison may be ill-formed if
166
- overload resolution finds usable candidates that do not otherwise meet
167
- the requirements implied by the defined expression. — *end note*]
168
 
169
  Let `R` be the declared return type of a defaulted three-way comparison
170
  operator function, and let `xᵢ` be the elements of the expanded list of
171
  subobjects for an object `x` of type `C`.
172
 
@@ -230,5 +207,248 @@ struct C {
230
  };
231
  ```
232
 
233
  — *end example*]
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  ### Defaulted comparison operator functions <a id="class.compare.default">[[class.compare.default]]</a>
4
 
5
  A defaulted comparison operator function [[over.binary]] for some class
6
  `C` shall be a non-template function that is
7
 
8
+ - a non-static member or friend of `C` and
9
+ - either has two parameters of type `const C&` or two parameters of type
10
+ `C`, where the implicit object parameter (if any) is considered to be
11
+ the first parameter.
 
12
 
13
+ Name lookups in the implicit definition [[dcl.fct.def.default]] of a
14
+ comparison operator function are performed from a context equivalent to
15
+ its *function-body*. A definition of a comparison operator as defaulted
16
+ that appears in a class shall be the first declaration of that function.
 
 
 
17
 
18
  A defaulted `<=>` or `==` operator function for class `C` is defined as
19
  deleted if any non-static data member of `C` is of reference type or `C`
20
  has variant members [[class.union.anon]].
21
 
 
24
  - `a` or `b` is of class or enumeration type and overload resolution
25
  [[over.match]] as applied to `a @ b` results in a usable candidate, or
26
  - neither `a` nor `b` is of class or enumeration type and `a @ b` is a
27
  valid expression.
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  If the *member-specification* does not explicitly declare any member or
30
  friend named `operator==`, an `==` operator function is declared
31
  implicitly for each three-way comparison operator function defined as
32
  defaulted in the *member-specification*, with the same access and
33
  *function-definition* and in the same class scope as the respective
34
  three-way comparison operator function, except that the return type is
35
  replaced with `bool` and the *declarator-id* is replaced with
36
  `operator==`.
37
 
38
+ [*Note 1*: Such an implicitly-declared `==` operator for a class `X` is
39
  defined as defaulted in the definition of `X` and has the same
40
  *parameter-declaration-clause* and trailing *requires-clause* as the
41
  respective three-way comparison operator. It is declared with `friend`,
42
  `virtual`, `constexpr`, or `consteval` if the three-way comparison
43
  operator function is so declared. If the three-way comparison operator
44
  function has no *noexcept-specifier*, the implicitly-declared `==`
45
  operator function has an implicit exception specification
46
+ [[except.spec]] that can differ from the implicit exception
47
  specification of the three-way comparison operator
48
  function. — *end note*]
49
 
50
  [*Example 1*:
51
 
 
59
  };
60
  ```
61
 
62
  — *end example*]
63
 
64
+ [*Note 2*: The `==` operator function is declared implicitly even if
65
  the defaulted three-way comparison operator function is defined as
66
  deleted. — *end note*]
67
 
68
  The direct base class subobjects of `C`, in the order of their
69
  declaration in the *base-specifier-list* of `C`, followed by the
 
109
  ### Three-way comparison <a id="class.spaceship">[[class.spaceship]]</a>
110
 
111
  The *synthesized three-way comparison* of type `R` [[cmp.categories]] of
112
  glvalues `a` and `b` of the same type is defined as follows:
113
 
114
+ - If `a <=> b` is usable [[class.compare.default]] and can be explicitly
115
+ converted to `R` using `static_cast`, `static_cast<R>(a <=> b)`.
116
  - Otherwise, if overload resolution for `a <=> b` is performed and finds
117
  at least one viable candidate, the synthesized three-way comparison is
118
  not defined.
119
  - Otherwise, if `R` is not a comparison category type, or either the
120
  expression `a == b` or the expression `a < b` is not usable, the
 
137
  a < b ? partial_ordering::less :
138
  b < a ? partial_ordering::greater :
139
  partial_ordering::unordered
140
  ```
141
 
142
+ [*Note 1*: A synthesized three-way comparison is ill-formed if overload
143
+ resolution finds usable candidates that do not otherwise meet the
144
+ requirements implied by the defined expression. — *end note*]
145
 
146
  Let `R` be the declared return type of a defaulted three-way comparison
147
  operator function, and let `xᵢ` be the elements of the expanded list of
148
  subobjects for an object `x` of type `C`.
149
 
 
207
  };
208
  ```
209
 
210
  — *end example*]
211
 
212
+ <!-- Link reference definitions -->
213
+ [basic.align]: basic.md#basic.align
214
+ [basic.compound]: basic.md#basic.compound
215
+ [basic.def]: basic.md#basic.def
216
+ [basic.def.odr]: basic.md#basic.def.odr
217
+ [basic.life]: basic.md#basic.life
218
+ [basic.link]: basic.md#basic.link
219
+ [basic.lookup]: basic.md#basic.lookup
220
+ [basic.lookup.elab]: basic.md#basic.lookup.elab
221
+ [basic.lval]: expr.md#basic.lval
222
+ [basic.scope.class]: basic.md#basic.scope.class
223
+ [basic.scope.pdecl]: basic.md#basic.scope.pdecl
224
+ [basic.scope.scope]: basic.md#basic.scope.scope
225
+ [basic.start.dynamic]: basic.md#basic.start.dynamic
226
+ [basic.start.static]: basic.md#basic.start.static
227
+ [basic.start.term]: basic.md#basic.start.term
228
+ [basic.stc.auto]: basic.md#basic.stc.auto
229
+ [basic.stc.static]: basic.md#basic.stc.static
230
+ [basic.stc.thread]: basic.md#basic.stc.thread
231
+ [basic.types]: basic.md#basic.types
232
+ [class]: #class
233
+ [class.abstract]: #class.abstract
234
+ [class.access]: #class.access
235
+ [class.access.base]: #class.access.base
236
+ [class.access.general]: #class.access.general
237
+ [class.access.nest]: #class.access.nest
238
+ [class.access.spec]: #class.access.spec
239
+ [class.access.virt]: #class.access.virt
240
+ [class.base.init]: #class.base.init
241
+ [class.bit]: #class.bit
242
+ [class.cdtor]: #class.cdtor
243
+ [class.compare]: #class.compare
244
+ [class.compare.default]: #class.compare.default
245
+ [class.compare.secondary]: #class.compare.secondary
246
+ [class.conv]: #class.conv
247
+ [class.conv.ctor]: #class.conv.ctor
248
+ [class.conv.fct]: #class.conv.fct
249
+ [class.conv.general]: #class.conv.general
250
+ [class.copy.assign]: #class.copy.assign
251
+ [class.copy.ctor]: #class.copy.ctor
252
+ [class.copy.elision]: #class.copy.elision
253
+ [class.ctor]: #class.ctor
254
+ [class.ctor.general]: #class.ctor.general
255
+ [class.default.ctor]: #class.default.ctor
256
+ [class.derived]: #class.derived
257
+ [class.derived.general]: #class.derived.general
258
+ [class.dtor]: #class.dtor
259
+ [class.eq]: #class.eq
260
+ [class.expl.init]: #class.expl.init
261
+ [class.free]: #class.free
262
+ [class.friend]: #class.friend
263
+ [class.inhctor.init]: #class.inhctor.init
264
+ [class.init]: #class.init
265
+ [class.init.general]: #class.init.general
266
+ [class.local]: #class.local
267
+ [class.mem]: #class.mem
268
+ [class.mem.general]: #class.mem.general
269
+ [class.member.lookup]: basic.md#class.member.lookup
270
+ [class.mfct]: #class.mfct
271
+ [class.mfct.non.static]: #class.mfct.non.static
272
+ [class.mi]: #class.mi
273
+ [class.name]: #class.name
274
+ [class.nest]: #class.nest
275
+ [class.paths]: #class.paths
276
+ [class.pre]: #class.pre
277
+ [class.prop]: #class.prop
278
+ [class.protected]: #class.protected
279
+ [class.qual]: basic.md#class.qual
280
+ [class.spaceship]: #class.spaceship
281
+ [class.static]: #class.static
282
+ [class.static.data]: #class.static.data
283
+ [class.static.general]: #class.static.general
284
+ [class.static.mfct]: #class.static.mfct
285
+ [class.temporary]: basic.md#class.temporary
286
+ [class.union]: #class.union
287
+ [class.union.anon]: #class.union.anon
288
+ [class.union.general]: #class.union.general
289
+ [class.virtual]: #class.virtual
290
+ [cmp.categories]: support.md#cmp.categories
291
+ [cmp.categories.pre]: support.md#cmp.categories.pre
292
+ [cmp.partialord]: support.md#cmp.partialord
293
+ [cmp.strongord]: support.md#cmp.strongord
294
+ [cmp.weakord]: support.md#cmp.weakord
295
+ [conv]: expr.md#conv
296
+ [conv.mem]: expr.md#conv.mem
297
+ [conv.ptr]: expr.md#conv.ptr
298
+ [conv.rval]: expr.md#conv.rval
299
+ [dcl.array]: dcl.md#dcl.array
300
+ [dcl.attr.nouniqueaddr]: dcl.md#dcl.attr.nouniqueaddr
301
+ [dcl.constexpr]: dcl.md#dcl.constexpr
302
+ [dcl.decl]: dcl.md#dcl.decl
303
+ [dcl.enum]: dcl.md#dcl.enum
304
+ [dcl.fct]: dcl.md#dcl.fct
305
+ [dcl.fct.def]: dcl.md#dcl.fct.def
306
+ [dcl.fct.def.coroutine]: dcl.md#dcl.fct.def.coroutine
307
+ [dcl.fct.def.default]: dcl.md#dcl.fct.def.default
308
+ [dcl.fct.def.delete]: dcl.md#dcl.fct.def.delete
309
+ [dcl.fct.def.general]: dcl.md#dcl.fct.def.general
310
+ [dcl.fct.default]: dcl.md#dcl.fct.default
311
+ [dcl.fct.spec]: dcl.md#dcl.fct.spec
312
+ [dcl.init]: dcl.md#dcl.init
313
+ [dcl.init.aggr]: dcl.md#dcl.init.aggr
314
+ [dcl.init.general]: dcl.md#dcl.init.general
315
+ [dcl.init.list]: dcl.md#dcl.init.list
316
+ [dcl.init.ref]: dcl.md#dcl.init.ref
317
+ [dcl.inline]: dcl.md#dcl.inline
318
+ [dcl.meaning]: dcl.md#dcl.meaning
319
+ [dcl.name]: dcl.md#dcl.name
320
+ [dcl.spec.auto]: dcl.md#dcl.spec.auto
321
+ [dcl.stc]: dcl.md#dcl.stc
322
+ [dcl.type.cv]: dcl.md#dcl.type.cv
323
+ [dcl.type.elab]: dcl.md#dcl.type.elab
324
+ [dcl.type.simple]: dcl.md#dcl.type.simple
325
+ [dcl.typedef]: dcl.md#dcl.typedef
326
+ [depr.impldec]: future.md#depr.impldec
327
+ [depr.static.constexpr]: future.md#depr.static.constexpr
328
+ [diff.class]: compatibility.md#diff.class
329
+ [except.ctor]: except.md#except.ctor
330
+ [except.handle]: except.md#except.handle
331
+ [except.pre]: except.md#except.pre
332
+ [except.spec]: except.md#except.spec
333
+ [except.throw]: except.md#except.throw
334
+ [expr.ass]: expr.md#expr.ass
335
+ [expr.call]: expr.md#expr.call
336
+ [expr.cast]: expr.md#expr.cast
337
+ [expr.const]: expr.md#expr.const
338
+ [expr.const.cast]: expr.md#expr.const.cast
339
+ [expr.delete]: expr.md#expr.delete
340
+ [expr.dynamic.cast]: expr.md#expr.dynamic.cast
341
+ [expr.eq]: expr.md#expr.eq
342
+ [expr.new]: expr.md#expr.new
343
+ [expr.prim.id]: expr.md#expr.prim.id
344
+ [expr.prim.id.dtor]: expr.md#expr.prim.id.dtor
345
+ [expr.prim.id.qual]: expr.md#expr.prim.id.qual
346
+ [expr.prim.this]: expr.md#expr.prim.this
347
+ [expr.ref]: expr.md#expr.ref
348
+ [expr.reinterpret.cast]: expr.md#expr.reinterpret.cast
349
+ [expr.rel]: expr.md#expr.rel
350
+ [expr.static.cast]: expr.md#expr.static.cast
351
+ [expr.sub]: expr.md#expr.sub
352
+ [expr.throw]: expr.md#expr.throw
353
+ [expr.type.conv]: expr.md#expr.type.conv
354
+ [expr.typeid]: expr.md#expr.typeid
355
+ [expr.unary.op]: expr.md#expr.unary.op
356
+ [intro.execution]: basic.md#intro.execution
357
+ [intro.object]: basic.md#intro.object
358
+ [namespace.udecl]: dcl.md#namespace.udecl
359
+ [over]: over.md#over
360
+ [over.ass]: over.md#over.ass
361
+ [over.best.ics]: over.md#over.best.ics
362
+ [over.binary]: over.md#over.binary
363
+ [over.ics.ref]: over.md#over.ics.ref
364
+ [over.match]: over.md#over.match
365
+ [over.match.best]: over.md#over.match.best
366
+ [over.match.call]: over.md#over.match.call
367
+ [over.match.copy]: over.md#over.match.copy
368
+ [over.match.funcs]: over.md#over.match.funcs
369
+ [over.oper]: over.md#over.oper
370
+ [over.over]: over.md#over.over
371
+ [special]: #special
372
+ [stmt.dcl]: stmt.md#stmt.dcl
373
+ [stmt.return]: stmt.md#stmt.return
374
+ [string.classes]: strings.md#string.classes
375
+ [temp.arg]: temp.md#temp.arg
376
+ [temp.constr]: temp.md#temp.constr
377
+ [temp.constr.order]: temp.md#temp.constr.order
378
+ [temp.deduct.guide]: temp.md#temp.deduct.guide
379
+ [temp.dep.type]: temp.md#temp.dep.type
380
+ [temp.expl.spec]: temp.md#temp.expl.spec
381
+ [temp.explicit]: temp.md#temp.explicit
382
+ [temp.friend]: temp.md#temp.friend
383
+ [temp.inst]: temp.md#temp.inst
384
+ [temp.mem]: temp.md#temp.mem
385
+ [temp.param]: temp.md#temp.param
386
+ [temp.pre]: temp.md#temp.pre
387
+ [temp.spec.partial]: temp.md#temp.spec.partial
388
+ [temp.variadic]: temp.md#temp.variadic
389
+ [term.incomplete.type]: basic.md#term.incomplete.type
390
+ [term.layout.compatible.type]: basic.md#term.layout.compatible.type
391
+ [term.object.representation]: basic.md#term.object.representation
392
+ [term.odr.use]: basic.md#term.odr.use
393
+ [term.padding.bits]: basic.md#term.padding.bits
394
+
395
+ [^1]: This ensures that two subobjects that have the same class type and
396
+ that belong to the same most derived object are not allocated at the
397
+ same address [[expr.eq]].
398
+
399
+ [^2]: See, for example, `<cstring>`.
400
+
401
+ [^3]: This implies that the reference parameter of the
402
+ implicitly-declared copy constructor cannot bind to a `volatile`
403
+ lvalue; see  [[diff.class]].
404
+
405
+ [^4]: Because a template assignment operator or an assignment operator
406
+ taking an rvalue reference parameter is never a copy assignment
407
+ operator, the presence of such an assignment operator does not
408
+ suppress the implicit declaration of a copy assignment operator.
409
+ Such assignment operators participate in overload resolution with
410
+ other assignment operators, including copy assignment operators,
411
+ and, if selected, will be used to assign an object.
412
+
413
+ [^5]: This implies that the reference parameter of the
414
+ implicitly-declared copy assignment operator cannot bind to a
415
+ `volatile` lvalue; see  [[diff.class]].
416
+
417
+ [^6]: These conversions are considered as standard conversions for the
418
+ purposes of overload resolution [[over.best.ics]], [[over.ics.ref]]
419
+ and therefore initialization [[dcl.init]] and explicit casts
420
+ [[expr.static.cast]]. A conversion to `void` does not invoke any
421
+ conversion function [[expr.static.cast]]. Even though never directly
422
+ called to perform a conversion, such conversion functions can be
423
+ declared and can potentially be reached through a call to a virtual
424
+ conversion function in a base class.
425
+
426
+ [^7]: The use of the `virtual` specifier in the declaration of an
427
+ overriding function is valid but redundant (has empty semantics).
428
+
429
+ [^8]: If all virtual functions are immediate functions, the class is
430
+ still polymorphic even if its internal representation does not
431
+ otherwise require any additions for that polymorphic behavior.
432
+
433
+ [^9]: A function with the same name but a different parameter list
434
+ [[over]] as a virtual function is not necessarily virtual and does
435
+ not override. Access control [[class.access]] is not considered in
436
+ determining overriding.
437
+
438
+ [^10]: Multi-level pointers to classes or references to multi-level
439
+ pointers to classes are not allowed.
440
+
441
+ [^11]: Access permissions are thus transitive and cumulative to nested
442
+ and local classes.
443
+
444
+ [^12]: As specified previously in [[class.access]], private members of a
445
+ base class remain inaccessible even to derived classes unless friend
446
+ declarations within the base class definition are used to grant
447
+ access explicitly.
448
+
449
+ [^13]: This additional check does not apply to other members, e.g.,
450
+ static data members or enumerator member constants.
451
+
452
+ [^14]: Because only one object is destroyed instead of two, and one
453
+ copy/move constructor is not executed, there is still one object
454
+ destroyed for each one constructed.