Concepts library (since C++20)
La biblioteca de conceptos proporciona definiciones de conceptos fundamentales de biblioteca que pueden utilizarse para realizar validación en tiempo de compilación de argumentos de plantilla y realizar despacho de funciones basado en propiedades de tipos. Estos conceptos proporcionan una base para el razonamiento ecuacional en programas.
La mayoría de los conceptos en la biblioteca estándar imponen requisitos tanto sintácticos como semánticos. Se dice que un concepto estándar está satisfecho si se cumplen sus requisitos sintácticos, y está modelado si está satisfecho y también se cumplen sus requisitos semánticos (si los hay).
En general, solo los requisitos sintácticos pueden ser verificados por el compilador. Si la validez o el significado de un programa depende de si una secuencia de argumentos de plantilla modela un concepto, y el concepto se satisface pero no se modela, o si un requisito semántico no se cumple en el punto de uso, el programa está mal formado, no se requiere diagnóstico .
Contenidos |
Preservación de la igualdad
Una expresión es equality-preserving si produce salidas iguales dadas entradas iguales, donde
- las entradas consisten en sus operandos (no necesariamente haciendo la expresión semánticamente válida), y
- las salidas consisten en su resultado y todas las modificaciones a los operandos por la expresión, si las hay
donde, por conveniencia de redacción, sus "operandos" se refieren a sus subexpresiones más grandes que consisten en una id-expression o invocaciones de std::move , std::forward , y std::declval .
La calificación cv y la categoría de valor de cada operando se determina asumiendo que cada parámetro de tipo de plantilla en su tipo denota un tipo de objeto completo no-array sin calificación cv.
Toda expresión que se requiere que sea de preservación de igualdad debe además ser estable, es decir, dos evaluaciones de la misma con los mismos objetos de entrada deben tener salidas iguales sin ninguna modificación explícita intermedia de esos objetos de entrada.
A menos que se indique lo contrario, toda expresión utilizada en una requires expresión de los conceptos de la biblioteca estándar debe ser de preservación de igualdad, y la evaluación de la expresión solo puede modificar sus operandos no constantes. Los operandos que son constantes no deben modificarse.
En la biblioteca estándar, los siguientes conceptos pueden tener expresiones requires que no preservan la igualdad:
Variaciones de expresión implícita
Una requires expresión que utiliza una expresión que es no modificadora para algún operando constante lvalue también requiere implícitamente variaciones adicionales de esa expresión que acepten un lvalue no constante o (posiblemente constante) rvalue para el operando dado, a menos que dicha variación de expresión sea explícitamente requerida con semántica diferente.
Estas variaciones de expresión implícitas deben cumplir los mismos requisitos semánticos de la expresión declarada. El grado en que una implementación valida la sintaxis de las variaciones no está especificado.
template<class T> concept C = requires(T a, T b, const T c, const T d) { c == d; // expresión #1: no modifica los operandos a = std::move(b); // expresión #2: modifica ambos operandos a = c; // expresión #3: modifica el operando izquierdo `a` }; // La expresión #1 requiere implícitamente variaciones adicionales de expresión que // cumplan con los requisitos para c == d (incluyendo la no modificación), // como si las siguientes expresiones también hubieran sido declaradas: // ------ const == const ------- ------ const == non-const --- // c == b; // c == std::move(d); c == std::move(b); // std::move(c) == d; std::move(c) == b; // std::move(c) == std::move(d); std::move(c) == std::move(b); // -- non-const == const ------- -- non-const == non-const --- // a == d; a == b; // a == std::move(d); a == std::move(b); // std::move(a) == d; std::move(a) == b; // std::move(a) == std::move(d); std::move(a) == std::move(b); // La expresión #3 requiere implícitamente variaciones adicionales de expresión que // cumplan con los requisitos para a = c // (incluyendo la no modificación del segundo operando), // como si las expresiones a = b (variación de lvalue no constante) // y a = std::move(c) (variación de rvalue constante) hubieran sido declaradas. // Nota: Dado que la expresión #2 ya requiere explícitamente la variación de rvalue no constante // (a == std::move(b)), la expresión #3 ya no la requiere implícitamente. // El tipo T cumple con los requisitos sintácticos explícitamente establecidos del // concepto C anterior, pero no cumple con los requisitos implícitos adicionales // (es decir, T satisface pero no modela C): // un programa que requiere C<T> está mal formado (no se requiere diagnóstico). struct T { bool operator==(const T&) const { return true; } bool operator==(T&) = delete; };
Conceptos de la biblioteca estándar
|
Definido en el espacio de nombres
std
|
|
Conceptos fundamentales del lenguaje |
|
|
Definido en el encabezado
<concepts>
|
|
|
(C++20)
|
especifica que un tipo es el mismo que otro tipo
(concept) |
|
(C++20)
|
especifica que un tipo se deriva de otro tipo
(concept) |
|
(C++20)
|
especifica que un tipo es implícitamente convertible a otro tipo
(concept) |
|
(C++20)
|
especifica que dos tipos comparten un tipo de referencia común
(concept) |
|
(C++20)
|
especifica que dos tipos comparten un tipo común
(concept) |
|
(C++20)
|
especifica que un tipo es un tipo integral
(concept) |
|
(C++20)
|
especifica que un tipo es un tipo integral con signo
(concept) |
|
(C++20)
|
especifica que un tipo es un tipo integral que es sin signo
(concepto) |
|
(C++20)
|
especifica que un tipo es un tipo de punto flotante
(concept) |
|
(C++20)
|
especifica que un tipo puede ser asignado desde otro tipo
(concepto) |
|
(C++20)
|
especifica que un tipo puede ser intercambiado o que dos tipos pueden ser intercambiados entre sí
(concept) |
|
(C++20)
|
especifica que un objeto del tipo puede ser destruido
(concept) |
|
(C++20)
|
especifica que una variable del tipo puede ser construida desde o enlazada a un conjunto de tipos de argumentos
(concept) |
|
(C++20)
|
especifica que un objeto de un tipo puede ser construido por defecto
(concepto) |
|
(C++20)
|
especifica que un objeto de un tipo puede ser construido por movimiento
(concept) |
|
(C++20)
|
especifica que un objeto de un tipo puede ser copiado construido y movido construido
(concept) |
Conceptos de comparación |
|
|
Definido en el encabezado
<concepts>
|
|
|
(C++20)
|
especifica que un tipo puede ser utilizado en contextos booleanos
( concepto solo para exposición* ) |
|
especifica que el operador
==
es una relación de equivalencia
(concepto) |
|
|
especifica que los operadores de comparación en el tipo producen un orden total
(concept) |
|
|
Definido en el encabezado
<compare>
|
|
|
especifica que el operador
<=>
produce un resultado consistente en los tipos dados
(concept) |
|
Conceptos de objeto |
|
|
Definido en el encabezado
<concepts>
|
|
|
(C++20)
|
especifica que un objeto de un tipo puede ser movido e intercambiado
(concept) |
|
(C++20)
|
especifica que un objeto de un tipo puede ser copiado, movido e intercambiado
(concept) |
|
(C++20)
|
especifica que un objeto de un tipo puede ser copiado, movido, intercambiado y construido por defecto
(concept) |
|
(C++20)
|
especifica que un tipo es regular, es decir, es tanto
semiregular
como
equality_comparable
(concepto) |
Conceptos invocables |
|
|
Definido en el encabezado
<concepts>
|
|
|
(C++20)
|
especifica que un tipo invocable puede ser invocado con un conjunto dado de tipos de argumentos
(concept) |
|
(C++20)
|
especifica que un tipo invocable es un predicado booleano
(concept) |
|
(C++20)
|
especifica que un tipo invocable es una relación binaria
(concept) |
|
(C++20)
|
especifica que una
relation
impone una relación de equivalencia
(concepto) |
|
(C++20)
|
especifica que una
relation
impone un ordenamiento estricto débil
(concepto) |
Se pueden encontrar conceptos adicionales en la biblioteca de iteradores , la biblioteca de algoritmos , y la biblioteca de rangos .