Biblioteca de conceptos (C++20)
La biblioteca de conceptos proporciona definiciones de conceptos fundamentales de la biblioteca que se pueden utilizar para realizar la validación en tiempo de compilación de argumentos de plantilla y ejecutar el despacho de funciones en función de las propiedades de los tipos. Estos conceptos proporcionan una base para el razonamiento ecuacional en los programas.
La mayoría de los conceptos de 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 se satisface y también se cumplen sus requisitos semánticos (si los hay).
En general, el compilador solo puede comprobar los requisitos sintácticos. 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 no se cumple un requisito semántico en el momento de uso, el programa está mal formado, no se requiere diagnóstico.
Contenido |
[editar] Conservación de la igualdad
Una expresión es conservadora de la igualdad si da como resultado salidas iguales dadas entradas iguales, donde
- las entradas consisten en sus operandos (lo que no hace que la expresión sea semánticamente válida necesariamente), 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 la redacción, sus "operandos" se refieren a sus subexpresiones más grandes que consisten en una expresión-id o invocaciones de std::move, std::forward y std::declval.
La calificación const volatile y la categoría de valor de cada operando se determinan asumiendo que cada parámetro de plantilla con tipo, en su tipo, denota un tipo objeto no-array completo, sin calificación const volatile.
Cada expresión que se requiere que preserve la igualdad debe ser estable, es decir, dos evaluaciones de la misma con los mismos objetos de entrada deben tener resultados iguales sin ninguna modificación explícita de esos objetos de entrada.
A menos que se indique lo contrario, cada expresión utilizada en una expresión requires de los conceptos de la biblioteca estándar debe preservar la igualdad, y la evaluación de la expresión puede modificar solo sus operandos no constantes. Los operandos que son constantes no deben modificarse.
En la biblioteca estándar, se permite que los siguientes conceptos tengan expresiones requires que no preserven la igualdad:
[editar] Variaciones de expresión implícitas
Una expresión requires que utiliza una expresión que no modifica un operando l-valor constante también requiere implícitamente variaciones adicionales de esa expresión que aceptan un l-valor no constante o un r-valor (posiblemente constante) para el operando dado, a menos que dicha variación de expresión se requiera explícitamente con una semántica diferente.
Estas variaciones de expresión implícitas deben cumplir los mismos requisitos semánticos de la expresión declarada. No se especifica hasta qué punto una implementación valida la sintaxis de las variaciones.
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 de expresión adicionales que // cumplan con los requisitos para c == d (incluida la no modificación), // como si también se hubieran declarado las siguientes expresiones: // ------ 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 de expresión adicionales que // cumplan con los requisitos para a = c // (incluida la no modificación del segundo operando), // como si se hubieran declarado las expresiones a = b (variación l-valor no constante ) // y a = std::move(c) (variación r-valor constante). // Nota: Dado que la expresión #2 ya requiere la variación r-valor no constante // (a == std::move(b)) explícitamente, 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 requiere que C<T> esté mal formada (no se requiere diagnóstico). struct T { bool operator==(const T&) const { return true; } bool operator==(T&) = delete; };
[editar] Conceptos de la biblioteca estándar
Definido en el espacio de nombres
std | |
Conceptos centrales del lenguaje | |
Definido en el archivo de encabezado
<concepts> | |
(C++20) |
Especifica que un tipo es igual a otro tipo. (concepto) |
(C++20) |
Especifica que un tipo se deriva de otro tipo. (concepto) |
(C++20) |
Especifica que un tipo es convertible implícitamente a otro tipo. (concepto) |
(C++20) |
Especifica que dos tipos comparten un tipo referencia común. (concepto) |
(C++20) |
Especifica que dos tipos comparten un tipo común. (concepto) |
(C++20) |
Especifica que un tipo es un tipo entero. (concepto) |
(C++20) |
Especifica que un tipo es un tipo entero con signo. (concepto) |
(C++20) |
Especifica que un tipo es un tipo entero que no tiene signo. (concepto) |
(C++20) |
Especifica que un tipo es un tipo de punto flotante. (concepto) |
(C++20) |
Especifica que un tipo es asignable a partir de otro tipo (concepto) |
(C++20) |
especifica que un tipo se puede intercambiar o que dos tipos se pueden intercambiar entre sí (concepto) |
(C++20) |
Especifica que un objeto de este tipo puede destruirse. (concepto) |
(C++20) |
Especifica que una variable del tipo se puede construir a partir de un conjunto de tipos de argumentos o vincularla a ellos. (concepto) |
(C++20) |
especifica de un objeto de un tipo puede ser construido por defecto (concepto) |
(C++20) |
Especifica que un objeto de un tipo puede construirse por movimiento (concepto) |
(C++20) |
especifica que un objeto de un tipo se puede copiar y mover (concepto) |
Conceptos de comparación | |
Definido en el archivo de encabezado
<concepts> | |
(C++20) |
Especifica que un tipo puede usarse en contextos booleanos. (concepto solo de 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. (concepto) | |
Definido en el archivo de encabezado
<compare> | |
Especifica que el operador <=> produce un resultado consistente en los tipos dados. (concepto) | |
Conceptos de objetos | |
Definido en el archivo de encabezado
<concepts> | |
(C++20) |
Especifica que un objeto de un tipo se puede mover e intercambiar. (concepto) |
(C++20) |
Especifica que un objeto de un tipo se puede copiar, mover e intercambiar. (concepto) |
(C++20) |
Especifica que un objeto de un tipo se puede copiar, mover, intercambiar y construir por defecto. (concepto) |
(C++20) |
Especifica que un tipo es regular, es decir, es a la vez semiregular y equality_comparable . (concepto) |
Conceptos llamables | |
Definido en el archivo de encabezado
<concepts> | |
(C++20) |
especifica que un tipo invocable puede ser invocado con un conjunto dado de tipos de argumentos (concepto) |
(C++20) |
especifica que un tipo invocable es un predicado Booleano (concepto) |
(C++20) |
Especifica que un tipo invocable es una relación binaria. (concepto) |
(C++20) |
Especifica que una relación (relation ) impone una relación de equivalencia. (concepto) |
(C++20) |
especifica que una relación impone un orden débil estricto (concepto) |
Pueden encontrarse conceptos adicionales en la biblioteca de iteradores, la biblioteca de algoritmos y la biblioteca de rangos.