8 Expressions [expr]

8.10 Equality operators [expr.eq]

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].