equality-expression: relational-expression equality-expression == relational-expression equality-expression != relational-expression
Операторы == (равно) и != (не равно) группируются слева направо. Операнды должны иметь арифметику, перечисление, указатель или указатель на тип или тип члена std::nullptr_t. Операторы == и != оба дают результат true или false, т. Е. Результат типа bool. В каждом из приведенных ниже случаев операнды должны иметь один и тот же тип после применения указанных преобразований.
Если хотя бы один из операндов является указателем, pointer conversions, function pointer conversionsи qualification conversions выполняются на обоих операндов , чтобы привести их в свои composite pointer type. Сравнение указателей определяется следующим образом:
Если один указатель представляет адрес полного объекта, а другой указатель представляет адрес, следующий за последним элементом другого полного объекта,88 результат сравнения не указан.
В противном случае, если оба указателя равны нулю, оба указывают на одну и ту же функцию или на обе represent the same address, они сравниваются одинаково.
В противном случае указатели сравниваются неравно.
Если хотя бы один из операндов является указателем на член pointer to member conversions и qualification conversions выполняется для обоих операндов, чтобы привести их к их composite pointer type. Сравнение указателей на члены определяется следующим образом:
Если два указателя на члены являются значениями нулевого указателя на член, они сравниваются как равные.
Если только один из двух указателей на члены является значением нулевого указателя на член, они сравниваются неравно.
Если любой из них является указателем на виртуальную функцию-член, результат не указан.
Если один относится к члену класса, C1 а другой - к члену другого класса C2, где ни один из них не является базовым классом другого, результат не указан. [ Example:
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 ]
Если оба относятся к (возможно, различным) членам одного и того же union, они сравниваются как равные.
В противном случае два указателя на члены сравниваются как равные, если бы они ссылались на один и тот же член одного most derived object и того же подобъекта, если выполнялась косвенная ссылка на гипотетический объект соответствующего типа класса, в противном случае они сравниваются неравно. [ Example:
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); // false bool y = (pb == pl); // true
— end example ]
Два операнда типа std::nullptr_t или один операнд типа std::nullptr_t и другой константа нулевого указателя сравниваются равными.
Если два операнда сравниваются равными, результат true для == оператора и false для != оператора. Если два операнда не равны, результат будет false для == оператора и true для != оператора. В противном случае результат каждого из операторов не указан.
Если оба операнда относятся к арифметическому или перечислимому типу, обычные арифметические преобразования выполняются для обоих операндов; каждый из операторов должен уступить, true если указанное отношение истинно и false если оно ложно.
Для этой цели объект, не являющийся элементом массива, считается принадлежащим к одноэлементному массиву; см [expr.unary.op].