Espacios de nombres
Variantes
Acciones

Operadores de comparación

De cppreference.com
< cpp‎ | language
 
 
 
Expresiones
General
categorías de valores (lvalue, rvalue, xvalue)
orden de evaluación (puntos de secuencia)
expresiones constantes
Operadores
Operadores de asignación: a=b, a+=b, a-=b, a*=b, a/=b, a%=b, a&=b, a|=b, a^=b, a<<=b, a>>=b
Operadores aritméticos: +a, -a, a+b, a-b, a*b, a/b, a%b, ~a, a&b, a|b, a^b, a<<b, a>>b
Incremento y decremento: ++a, --a, a++, a--
Operadores lógicos: a||b, a&&b, !a
Operadores de comparación: a==b, a!=b, a<b, a>b, a<=b, a>=b, a<=>b(C++20)
Operadores de acceso a miembro: a[b], *a, &a, a->b, a.b, a->*b, a.*b
Otros operadores: a(...), a,b, a?b:c
sizeof
alignof (C++11)
expresión new
expresión delete
typeid
 

Compara los argumentos.

Nombre operador Sintaxis Sobrecargable Ejemplos de prototipo (para class T)
Como función miembro Como función libre (espacio de nombres)
igual a a == b Si bool T::operator ==(const T2 &b) const; bool operator ==(const T &a, const T2 &b);
no igual a a != b Si bool T::operator !=(const T2 &b) const; bool operator !=(const T &a, const T2 &b);
menor que a < b Si bool T::operator <(const T2 &b) const; bool operator <(const T &a, const T2 &b);
mayor que a > b Si bool T::operator >(const T2 &b) const; bool operator >(const T &a, const T2 &b);
menor o igual que a <= b Si bool T::operator <=(const T2 &b) const; bool operator <=(const T &a, const T2 &b);
mayor o igual a a >= b Si bool T::operator >=(const T2 &b) const; bool operator >=(const T &a, const T2 &b);
comparación de tres vías (C++20) a <=> b Si /*ver descripción*/ T::operator <=>(const T2 &b) const; /*ver descripción*/ operator <=>(const T &a, const T2 &b);
Notas
  • Donde los operadores integrados devuelven bool, muchas sobrecargas definidas por usuario también devuelven bool por lo que los operadores definidos por usuario se pueden usar de la misma manera que los integrados. Sin embargo, en una sobrecarga de operador definida por usuario, se pueden usar cualquier tipo como tipo de retorno (incluyendo void).ser-defined operator overload, any type can be used as return type (including void).}}
  • T2 puede ser de cualquier tipo, incluyendo T

Contenido

[editar] Comparación de dos vías

Las expresiones del operador de comparación de dos vías tienen la forma

lhs < rhs (1)
lhs > rhs (2)
lhs <= rhs (3)
lhs >= rhs (4)
lhs == rhs (5)
lhs != rhs (6)
1) Devuelveverdadero si lhs es menor que rhs, falso en otro caso.
2) Devuelve verdadero si lhs es mayor que rhs, falso en otro caso.
3) Devuelve verdadero si lhs es menor o igual a rhs, falso en otro caso.
4) Devuelve verdadero si lhs es mayor o igual a rhs, falso en otro caso.
5) Devuelve verdadero si lhs es igual a rhs, falso en otro caso.
6) Devuelve verdadero si lhs no es igual a rhs, falso en otro caso.

En todos los casos, para los operadores integrados, lhs y rhs deben tener cualquier

  • tipo aritmético o enumerado (vea operadores de comparación aritmética más abajo)
  • tipo puntero (vea operadores de comparación de punteros más abajo)

después de la aplicación de las conversiones estándar lvalue a rvalue, matriz a puntero and función a puntero. La comparación está en desuso si ambos operandos tienen tipo matriz antes de la aplicación de estas conversiones. (desde C++20)

En cualquier caso, el resultado es un bool prvalue.

[editar] Los operadores aritméticos de comparación

Si los operandos tienen tipo aritmético o enumerado (sin y con ámbito), las conversiones aritméticas usuales se realizan en ambos operandos siguiendo las reglas de los operadores aritméticos. Los valores se comparan después de las conversiones:

[editar] Ejemplo

#include <iostream>
int main()
{
    std::cout << std::boolalpha;
    int n = -1;
 
    int n2 = 1;
    std::cout << " -1 == 1? " << (n == n2) << '\n'
              << "Comparando dos valores con signo:\n"
              << " -1  < 1? " << (n < n2) << '\n'
              << " -1  > 1? " << (n > n2) << '\n';
 
    unsigned int u = 1;
    std::cout << "Comparando con y sin signo:\n"
              << " -1  < 1? " << (n < u) << '\n'
              << " -1  > 1? " << (n > u) << '\n';
 
    unsigned char uc = 1;
    std::cout << "Comparando con signo y tipo menor sin signo:\n"
              << " -1  < 1? " << (n < uc) << '\n'
              << " -1  > 1? " << (n > uc) << '\n';
}

Salida:

 -1 == 1? false
Comparando dos valores con signo:
 -1  < 1? true
 -1  > 1? false
Comparando con y sin signo:
 -1  < 1? false
 -1  > 1? true
Comparando con signo y tipo menor sin signo:
 -1  < 1? true
 -1  > 1? false


[editar] Operadores de comparación de puntero

Los operadores de comparación se pueden usar para comparar dos punteros (o punteros a miembro, para operator== y operator!= solamente), o un puntero a miembro (desde C++14) y una constante puntero nulo, o dos constantes puntero nulo (pero solamente mientras uno de ellos sea std::nullptr_t: la comparación de NULL y NULL sigue las reglas aritméticas de comparación) (hasta C++14).

Primero, conversiones de puntero (conversiones de puntero a miembro si los argumentos son punteros a miembro), conversiones de puntero a función, (desde C++17) y conversiones de calificación se aplican a ambos operandos para obtener el tipo compuesto de puntero, como sigue:

1) Si ambos operandos son punteros nulos constantes, el tipo puntero compuesto es std::nullptr_t
2) Si un operando es un puntero nulo constante, y el otro es un puntero, el tipo compuesto es exactamente el tipo puntero
3) Si un operando es puntero a cv1 void y el otro es un puntero a cv2 T para cualquier tipo T, donde T es un tipo objeto o void, el tipo compuesto es "puntero a cv12 void", donde cv12 es la unión de cv1 y cv2
4) Si ambos operandos son punteros al mismo tipo, con diferente calificación constante/volátil, el compuesto es un puntero al mismo tipo con calificación constante/volátil que es la unión de las calificaciones de los argumentos.
(hasta C++14)
4) Si los tipos de los operandos son P1, un puntero a (posiblemente calificado constante/volátil) T1, y P2, un puntero a (posiblemente calificado constante/volátil) T2, y si T1 es el mismo que T2 o es clase base de T2, entonces el tipo de puntero compuesto es el tipo combinación constante/volátil de P1 y P2. En otro caso, si T2 es una clase base de T1, entonces el tipo de puntero compuesto es el tipo combinación constante/volátil) de P2 y P1.
5) Si los tipos de los operandos son MP1, puntero a miembro de T1 de tipo (posiblemente calificado constante/volátil) U1 y MP2, puntero a miembro de T2 de tipo (posiblemente calificado constante/volátil) U2, y si T1 es el mismo o derivado de T2, entonces el tipo del puntero compuesto es el tipo combinación constante/volátil de MP1 y MP2. En otro caso, si T2 es derivado de T1, entonces el tipo de puntero compuesto es de tipo combinado constante/volátil de MP2 y MP1.
6) Si los tipos de los operandos P1 y P2 son tipos puntero mixto multinivel y puntero a miembro con el mismo número de niveles que solo difieren en las calificaciones constante/volátil en alguno de los niveles, el tipo de puntero compuesto es la combinación constante/volátil de P1 y P2.

En la definición anterior, tipo combinado constante/volátil de dos tipos puntero P1 y P2 es un tipo P3 que tiene el mismo número de niveles y tipo en cada nivel que P1, excepto que las calificaciones constante/volátil de cada nivel se establecen como sigue:

a) en cada nivel distinto del nivel superior, la unión de las calificaciones constante/volátil de ese nivel de P1 y P2
b) si el resultado de la calificación constante/volátil en cualquier nivel es diferente de las calificaciones constante/volátil de P1 y P2 en el mismo nivel, entonces se añade const a todos los niveles entre el nivel superior y este.

Por ejemplo, el tipo puntero compuesto de void* y const int* es const void*. El tipo de puntero compuesto de int** y const int** es const int* const*. Tenga en cuenta que hasta C++14, int** y const int** no se podían comparar.

(desde C++14)

Añadido a lo anterior, el tipo de puntero compuesto entre un puntero a función y un puntero a función noexcept (siempre que el tipo de unión sea el mismo) es un puntero a función.

(desde C++17)

Tenga en cuenta que esto implica que cualquier puntero se puede comparar con void*.

El resultado de comparar dos punteros a objetos (después de las conversiones) se define como:

1) Si dos punteros apuntan a diferentes elementos de la misma matriz, o a subobjetos con diferentes elementos de la misma matriz, el puntero al elemento con mayor índice es mayor en la comparación. En otras palabras, el resultado de comparar punteros es el mismo que comparar los ínidces de los elementos a los que apuntan.
2) Si un puntero apunta a un elemento de una matriz, o a un subobjeto de un elemento de la matriz, y el otro puntero apunta a uno pasado el último elemento de la matriz, el último puntero es mayor en la comparación. Punteros a un solo objeto se tratan como punteros a una matriz de un elemento: &obj+1 es mayor que &obj. (desde C++17)
3) Si, en un objeto de tipo clase no unión, dos puntero apuntan a diferentes miembros dato no estáticos con el mismo acceso a miembro, o a subobjetos o elementos de matriz de dichos miembros, recursivamente, el puntero al miembro declarado en último lugar es mayor en la comparación. En otras palabras, los miembros de clase en cada uno de los tres modos de acceso a miembro se posicionan en memoria en el orden de la declaración.

El resultado de la comparación de igualdad de dos punteros (después de las conversiones) se define como:

1) Si ambos punteros tienen valor puntero nulo, se comparan iguales.
2) Si los punteros son punteros función y apuntan a la misma función, se comparan iguales.
3) Si los punteros son punteros a objetos y representan la misma dirección, se comparan iguales (esto incluye dos puntero a miembros no estáticos de la misma unión, punteros a estructuras de diseño estándar y su primer miembro, puntero relacionados por reinterpret_cast, etc.).
4) Todos los demás punteros se comparan no iguales.

El resultado de la comparación de dos punteros a miembros (después de las conversiones) se define como:

1) Si ambos puntero a miembro son valores puntero a miembro nulo, se comparan igual.
2) En otro caso, si solo uno de los dos punteros a miembro es valor puntero a miembro nulo, se comparan no iguales.
3) En otro caso, si cualquiera de los dos es un puntero a una función miembro virtual, el resultado es indeterminado.
4) En otro caso, dos punteros a miembro se comparan igual si y solo si se refieren al mismo miembro del mismo objeto más derivado o al mismo subobjeto si fueron referenciados con un objeto hipotético del tipo de clase asociado.
5) En otro caso se comparan no igual.

Si un puntero p se compara igual al puntero q, p<=q y p>=q dan verdadero, y p<q y p>q dan falso.

Si un puntero p se compara mayor que un puntero q, entonces p>=q, p>q, q<=p, y q<p danverdadero, y p<=q, p<q, q>=p, y q>p dan falso.

Si dos punteros no se especifican para comparar mayor o igual, el resultado de la comparación es inespecífica. El resultado puede ser no determinista, y no necesita ser consistentemente igual para múltiples evaluaciones de la misma expresión con los mismos operandos en la misma ejecución del programa:

int x, y;
 
bool f(int* p, int* q) { return p < q; }
 
assert(f(&x, &y) == f(&x, &y)); // puede fallar en una implementación conforme

En la resolución de sobrecarga de operadores definidos por usuario, para cada par de tios aritméticos promocionados L y R, incluyendo tipos enumerados, los siguientes modelos de función participan en la resolución de sobrecarga:

bool operator<(L, R);
bool operator>(L, R);
bool operator<=(L, R);
bool operator>=(L, R);
bool operator==(L, R);
bool operator!=(L, R);

Para cada tipo P que es puntero a objeto o puntero a función o std::nullptr_t (hasta C++14), los siguientes modelos de función participan en la resolución de sobrecarga:

bool operator<(P, P);
bool operator>(P, P);
bool operator<=(P, P);
bool operator>=(P, P);
bool operator==(P, P);
bool operator!=(P, P);

Para cada tipo MP que es puntero a objeto miembro o puntero a función miembro o std::nullptr_t, los siguientes modelos de función participan en la resolución de sobrecarga:

bool operator==(MP, MP);
bool operator!=(MP, MP);

[editar] Notas

Debido a que estos operadores se agrupan de izquierda a derecha, la expresión a<b<c se evalúa (a<b)<c, y no a<(b<c), ni (a<b)&&(b<c).

Un requisito común para el operador < definido por el usuario es orden estricto débil. En particular, se requiere por los algoritmos estándar y contenedores que trabajan con tipos Comparar: std::sort, std::max_element, std::map, etc.

Aunque los resultados de comparar punteros de origen aleatorio (por ejemplo, no todos apuntan a miembros de la misma matriz) es inespecífica, bastantes implementaciones proveen orden estricto total de punteros, por ejemplo, si estan implementados como direcciones en espacio virtual de direcciones continuo. Aquellas implementaciones que no (por ejemplo donde no todos los bits del puntero son parte de una dirección de memoria y tienen que ser ignorados para la comparación, o un cáluclo adicional se requiere o de otra manera el puntero y el entero no es una relación 1 a 1), provee una especialización de std::less para los punteros que tienen esta garantía. Esto hace posible usar todos los punteros de origen aleatorio como claves en contenedores asociativos estándar como std::set o std::map.

Para los tipos que son Comparable Igualdad y Comparable Menor Que, la biblioteca estándar de C++ hace una distinción entre igualdad, que es el valor de la expresión a == b y equivalencia, que es el valor de la expresión!(a < b) && !(b < a).

La comparación entre punteros y constantes puntero nulo se eliminó en C++14

void f(char * p)
{
  if (p > 0) { ... } // OK en C++98..C++11, no compila en C++14
  if (p > nullptr) { ... } // OK en C++11, no compila en C++14
}

Comparación de tres vías

El operador de comparación de tres vías tiene la forma

lhs <=> rhs (1)

La expresión devuelve un objeto tal que

  • (a <=> b) < 0 silhs < rhs
  • (a <=> b) > 0 si lhs > rhs
  • (a <=> b) == 0 si lhs y rhs son iguales/equivalentes.

Si uno de los operandos es de tipo bool y el otro no, el programa está mal formado.

Si ambos operandos tienen tipos aritméticos, o si un operando tiene tipo enumerado sin ámbito y el otro entero, se aplican a los operandos las conversiones aritméticas usuales, y luego

  • Si se requiere una conversión, otra que no sea de tipo entero a coma flotante, el programa esta mal formado.
  • En otro caso, si los operandos tienen tipo entero, el operador produce un prvalue de tipo std::strong_ordering:
  • std::strong_ordering::equal si ambos operandos son aritméticamente iguales,
  • std::strong_ordering::less si el primer operando es aritméticamente menor que el segundo,
  • std::strong_ordering::greater en otro caso.
  • En otro caso, los operandos tienen tipo coma flotante, y el opreador produce un prvalue de tipo std::partial_ordering. La expresión a <=> b produce
  • std::partial_ordering::less si a es menor que b
  • std::partial_ordering::greater si a es mayor que b
  • std::partial_ordering::equivalent si a es equivalente a b (-0 <=> +0 es equivalente)
  • std::partial_ordering::unordered (NaN <=> algo es sin orden)

Si ambos operandos tienen el mismo tipo enumerado E, el operador produce el resultado de convertir los operandos a tipo subyacente de E y aplicar <=> a los operandos convertidos.

Si al menos uno de los operandos es un puntero o puntero a miembro se aplica conversiones matriz a puntero, conversiones puntero derivado a base, conversiones puntero a función, y conversiones de calificación como sea necesario parea convertir ambos operandos al mismo tipo de puntero.

Si el tipo puntero resultante es un puntero a función, un puntero a miembro, o std::nullptr_t, p <=> q devuelve un prvalue de tipo std::strong_equality:

  • std::strong_equality::equal sip == q
  • std::strong_equality::unequal si p != q
  • resultado inespecífico si la comparación de igualdad no está especificada para estos valores de puntero

Si el tipo de puntero resultante es un tipo puntero a objeto, p <=> q devulve un prvalue de tipo strong_ordering:

  • std::strong_ordering::equal si p == q
  • std::strong_ordering::less si q > p
  • std::strong_ordering::greater si p > q.
  • resultado inespecífico si la comparación es inespecífica para estos valores de puntero (como cuando no apuntan al mismo objeto o matriz).

En la resolución de sobrecarga de operadores definidos por usuario, para tipos puntero o enumerado T, los siguientes modelos de función participan en la resolución de sobrecarga:

R operator<=>(T, T);

Donde R es el tipo categoría de orden definido anteriormente.

Para cada T que es un tipo puntero a miembro o de tipo std::nullptr_t, los siguientes modelos de función participan en la resolución de sobrecarga:

std::strong_equality operator<=>(T, T);

Notas

La comparación de tres vías se puede generar automáticamente para tipos clase, ver default comparisons

Si ambos operandos son matrices, la comparación de tres vías es mal formada excepto cuando se comparan miembros de clase de tipo matriz.

unsigned int i = 1;
auto r = -1 < i; // escollo existente: devuelve ‘false’
auto r2 = -1 <=> i; // Error: se requiere un conversión reducida


(desde C++20)


[editar] Biblioteca estándar

Los operadores de comparación están sobrecargados para muchas clases en la biblioteca estándar.

comprueba si los objetos se refieren al mismo tipo
(función miembro público de std::type_info) [editar]
compara dos codigos de error
(función) [editar]
compara condiciones de error y códigos de error
(función) [editar]
compara lexicográficamente los valores del par
(plantilla de función) [editar]
compara lexicográficamente los valores de la tupla
(plantilla de función) [editar]
compara el contenido
(función miembro público de std::bitset) [editar]
Compara dos instancias de asignador
(función miembro público de std::allocator) [editar]
se compara con otro unique_ptr o con nullptr
(plantilla de función) [editar]
compara con otro shared_ptr o con nullptr
(plantilla de función) [editar]
compara una std::function con nullptr
(plantilla de función) [editar]
compara dos duraciones de tiempo
(plantilla de función) [editar]
compara dos puntos de tiempo
(plantilla de función) [editar]
Compara dos instancias de scoped_allocator_adaptor
(función miembro público de std::scoped_allocator_adaptor) [editar]
compara los objetos std::type_info subyacentes
(función miembro público de std::type_index) [editar]
comparación lexicográfica de dos cadenas de texto
(plantilla de función) [editar]
comparación de igualdad entre objetos de configuración regional
(función miembro público de std::locale) [editar]
compara lexicográficamente los valores del array
(plantilla de función) [editar]
compara lexicográficamente los valores del deque
(plantilla de función) [editar]
compara lexicográficamente los valores del forward_list
(plantilla de función) [editar]
compara lexicográficamente los valores del list
(plantilla de función) [editar]
compara lexicográficamente los valores del vector
(plantilla de función) [editar]
compara lexicográficamente los valores del map
(plantilla de función) [editar]
compara lexicográficamente los valores del multimap
(plantilla de función) [editar]
compara lexicográficamente los valores del set
(plantilla de función) [editar]
compara lexicográficamente los valores del multiset
(plantilla de función) [editar]
compara los valores de la unordered_map
(plantilla de función) [editar]
compara los valores de la unordered_multimap
(plantilla de función) [editar]
compara los valores de la unordered_set
(plantilla de función) [editar]
compara los valores de la unordered_multiset
(plantilla de función) [editar]
compara lexicográficamente los valores del queue
(plantilla de función) [editar]
compara lexicográficamente los valores del stack
(plantilla de función) [editar]
compara los iteradores subyacentes
(plantilla de función) [editar]
compara los iteradores subyacentes
(plantilla de función) [editar]
compara dos istream_iterator
(plantilla de función) [editar]
compara dos istreambuf_iterator
(plantilla de función) [editar]
compara dos números complejos o un complejo y un escalar
(plantilla de función) [editar]
compara dos valarrays o un valarray con un valor
(plantilla de función) [editar]
compara los estados internos de dos motores de números pseudo-aleatorios
(función) [editar]
compara dos objetos de distribución
(función) [editar]
compara dos objetos sub_match
(plantilla de función) [editar]
comparación lexicográfica de los valores en dos std::match_result
(plantilla de función) [editar]
compara dos regex_iterator
(función miembro público de std::regex_iterator) [editar]
compara dos regex_token_iterator
(función miembro público de std::regex_token_iterator) [editar]
compara dos objetos thread::id
(función) [editar]


El espacio de nombres rel_ops proporciona los operadores genéricos !=, >, <=, y >=

Definido en la cabecera <utility>
Defined in namespace std::rel_ops
genera automáticamente operadores de comparación basados en operator== y operator< definidos por usuario
(plantilla de función) [editar]

[editar] Ver también

Precedencia de operadores

Sobrecarga de operadores

Operadores comunes
asignación incremento/decremento aritmético lógico comparación acceso a miembro otros

a = b
a = rvalue
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b

a[b]
*a
&a
a->b
a.b
a->*b
a.*b

a(...)
a, b
(type) a
? :

Operadores especiales

static_cast convierte de un tipo a otro tipo compatible
dynamic_cast convierte de clase base virtual a clase derivada
const_cast convierte de un tipo a otro compatible con diferentes calificadores constante/volátil
reinterpret_cast convierte el tipo a tipo incompatible
new asigna memoria
delete desasigna memoria
sizeof consulta el tamaño de un tipo
sizeof... consulta el tamaño de un parámetro de paquete (desde C++11)
typeid consulta la información de un tipo
noexcept comprueba si una expresión puede lanzar una excepción (desde C++11)
alignof consultas requisitos de alineación de un tipo (desde C++11)

Documentacion C de Operadores de comparación