187 lines
7.7 KiB
Markdown
187 lines
7.7 KiB
Markdown
[expr.eq]
|
||
|
||
# 7 Expressions [[expr]](./#expr)
|
||
|
||
## 7.6 Compound expressions [[expr.compound]](expr.compound#expr.eq)
|
||
|
||
### 7.6.10 Equality operators [expr.eq]
|
||
|
||
[equality-expression:](#nt:equality-expression "7.6.10 Equality operators [expr.eq]")
|
||
[*relational-expression*](expr.rel#nt:relational-expression "7.6.9 Relational operators [expr.rel]")
|
||
[*equality-expression*](#nt:equality-expression "7.6.10 Equality operators [expr.eq]") == [*relational-expression*](expr.rel#nt:relational-expression "7.6.9 Relational operators [expr.rel]")
|
||
[*equality-expression*](#nt:equality-expression "7.6.10 Equality operators [expr.eq]") != [*relational-expression*](expr.rel#nt:relational-expression "7.6.9 Relational operators [expr.rel]")
|
||
|
||
[1](#1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7512)
|
||
|
||
The == (equal to) and the != (not equal to) operators
|
||
group left-to-right[.](#1.sentence-1)
|
||
|
||
The
|
||
lvalue-to-rvalue ([[conv.lval]](conv.lval "7.3.2 Lvalue-to-rvalue conversion"))
|
||
and function-to-pointer ([[conv.func]](conv.func "7.3.4 Function-to-pointer conversion"))
|
||
standard conversions are performed on the operands[.](#1.sentence-2)
|
||
|
||
If one of the operands is a pointer or a null pointer constant ([[conv.ptr]](conv.ptr "7.3.12 Pointer conversions")),
|
||
the array-to-pointer conversion ([[conv.array]](conv.array "7.3.3 Array-to-pointer conversion")) is performed
|
||
on the other operand[.](#1.sentence-3)
|
||
|
||
[2](#2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7523)
|
||
|
||
The converted operands shall have scalar type[.](#2.sentence-1)
|
||
|
||
The operators== and != both yield true or false, i.e., a
|
||
result of type bool[.](#2.sentence-2)
|
||
|
||
In each case below, the operands shall have the
|
||
same type after the specified conversions have been applied[.](#2.sentence-3)
|
||
|
||
[3](#3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7529)
|
||
|
||
If at least one of the converted operands is a pointer,[pointer conversions](conv.ptr "7.3.12 Pointer conversions [conv.ptr]"),[function pointer conversions](conv.fctptr "7.3.14 Function pointer conversions [conv.fctptr]"), and[qualification conversions](conv.qual "7.3.6 Qualification conversions [conv.qual]") are performed on both operands to bring them to their [composite pointer type](expr.type#def:composite_pointer_type "7.2.2 Type [expr.type]")[.](#3.sentence-1)
|
||
|
||
Comparing pointers is defined as follows:
|
||
|
||
- [(3.1)](#3.1)
|
||
|
||
If one pointer represents the address of a complete object, and another
|
||
pointer represents the address one past the last element of a different
|
||
complete object,[66](#footnote-66 "As specified in [basic.compound], an object that is not an array element is considered to belong to a single-element array for this purpose.") the result of the comparison is unspecified[.](#3.1.sentence-1)
|
||
|
||
- [(3.2)](#3.2)
|
||
|
||
Otherwise, if the pointers are both null, both point to the samefunction, or both[represent the same address](basic.compound#def:represents_the_address "6.9.4 Compound types [basic.compound]"),
|
||
they compare equal[.](#3.2.sentence-1)
|
||
|
||
- [(3.3)](#3.3)
|
||
|
||
Otherwise, the pointers compare unequal[.](#3.3.sentence-1)
|
||
|
||
[4](#4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7559)
|
||
|
||
If at least one of the operands is a pointer to member,
|
||
pointer-to-member conversions ([[conv.mem]](conv.mem "7.3.13 Pointer-to-member conversions")),
|
||
function pointer conversions ([[conv.fctptr]](conv.fctptr "7.3.14 Function pointer conversions")), and
|
||
qualification conversions ([[conv.qual]](conv.qual "7.3.6 Qualification conversions"))
|
||
are performed on both operands to bring them to
|
||
their composite pointer type ([[expr.type]](expr.type "7.2.2 Type"))[.](#4.sentence-1)
|
||
|
||
Comparing pointers to members is defined as follows:
|
||
|
||
- [(4.1)](#4.1)
|
||
|
||
If two pointers to members are both the null member pointer value, they compare
|
||
equal[.](#4.1.sentence-1)
|
||
|
||
- [(4.2)](#4.2)
|
||
|
||
If only one of two pointers to members is the null member pointer value, they
|
||
compare unequal[.](#4.2.sentence-1)
|
||
|
||
- [(4.3)](#4.3)
|
||
|
||
If either is a pointer to a virtual member function, the result is unspecified[.](#4.3.sentence-1)
|
||
|
||
- [(4.4)](#4.4)
|
||
|
||
If one refers to a member of class C1 and the other refers to a member
|
||
of a different class C2, where neither is a base class of the other,
|
||
the result is unspecified[.](#4.4.sentence-1)
|
||
[*Example [1](#example-1)*: struct A {};struct B : A { int x; };struct C : A { int x; };
|
||
|
||
int A::*bx = (int(A::*))&B::x;int A::*cx = (int(A::*))&C::x;
|
||
|
||
bool b1 = (bx == cx); // unspecified â *end example*]
|
||
|
||
- [(4.5)](#4.5)
|
||
|
||
If both refer to (possibly different) members of the same [union](class.union "11.5 Unions [class.union]"),
|
||
they compare equal[.](#4.5.sentence-1)
|
||
|
||
- [(4.6)](#4.6)
|
||
|
||
Otherwise, two pointers to members compare equal if they would refer to the same member of
|
||
the same [most derived object](intro.object#def:most_derived_object "6.8.2 Object model [intro.object]") or the same subobject if
|
||
indirection with a hypothetical object of the associated
|
||
class type were performed, otherwise they compare unequal[.](#4.6.sentence-1)
|
||
[*Example [2](#example-2)*: struct B {int f();};struct L : B { };struct R : B { };struct D : L, R { };
|
||
|
||
int (B::*pb)() = &B::f;int (L::*pl)() = pb;int (R::*pr)() = pb;int (D::*pdl)() = pl;int (D::*pdr)() = pr;bool x = (pdl == pdr); // falsebool y = (pb == pl); // true â *end example*]
|
||
|
||
[5](#5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7625)
|
||
|
||
Two operands of type std::nullptr_t or one operand of typestd::nullptr_t and the other a null pointer constant compare equal[.](#5.sentence-1)
|
||
|
||
[6](#6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7629)
|
||
|
||
If both operands are of type std::meta::info,
|
||
they compare equal if both operands
|
||
|
||
- [(6.1)](#6.1)
|
||
|
||
are null reflection values,
|
||
|
||
- [(6.2)](#6.2)
|
||
|
||
represent values that are template-argument-equivalent ([[temp.type]](temp.type "13.6 Type equivalence")),
|
||
|
||
- [(6.3)](#6.3)
|
||
|
||
represent the same object,
|
||
|
||
- [(6.4)](#6.4)
|
||
|
||
represent the same entity,
|
||
|
||
- [(6.5)](#6.5)
|
||
|
||
represent the same annotation ([[dcl.attr.annotation]](dcl.attr.annotation "9.13.12 Annotations")),
|
||
|
||
- [(6.6)](#6.6)
|
||
|
||
represent the same direct base class relationship, or
|
||
|
||
- [(6.7)](#6.7)
|
||
|
||
represent equal data member descriptions ([[class.mem.general]](class.mem.general "11.4.1 General")),
|
||
|
||
and they compare unequal otherwise[.](#6.sentence-1)
|
||
|
||
[7](#7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7643)
|
||
|
||
If two operands compare equal, the result is true for
|
||
the == operator and false for the != operator[.](#7.sentence-1)
|
||
|
||
If two operands
|
||
compare unequal, the result is false for the == operator andtrue for the != operator[.](#7.sentence-2)
|
||
|
||
Otherwise, the result of each of the
|
||
operators is unspecified[.](#7.sentence-3)
|
||
|
||
[8](#8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7650)
|
||
|
||
If both operands are of arithmetic or enumeration type, the usual arithmetic
|
||
conversions ([[expr.arith.conv]](expr.arith.conv "7.4 Usual arithmetic conversions")) are performed on both operands; each of the operators shall yieldtrue if the specified relationship is true and false if it is
|
||
false[.](#8.sentence-1)
|
||
|
||
[66)](#footnote-66)[66)](#footnoteref-66)
|
||
|
||
As specified in [[basic.compound]](basic.compound "6.9.4 Compound types"),
|
||
an object that is not an array element is
|
||
considered to belong to a single-element array for this purpose[.](#footnote-66.sentence-1)
|