Init
This commit is contained in:
186
cppdraft/expr/eq.md
Normal file
186
cppdraft/expr/eq.md
Normal file
@@ -0,0 +1,186 @@
|
||||
[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)
|
||||
Reference in New Issue
Block a user