Concepto (C++)

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 22 de marzo de 2021; las comprobaciones requieren 18 ediciones .

El concepto  es una extensión de interfaz para las plantillas de lenguaje C++ publicadas en la especificación técnica ISO/IEC ISO TS 19217:2015 [1] . En esencia , un concepto es un conjunto de predicados booleanos ubicados detrás de una lista de parámetros de plantilla que se evalúan en el momento de la compilación del código fuente para establecer restricciones sobre las propiedades de los argumentos que se aceptan como parámetros de plantilla [2] .

La introducción de conceptos está asociada con el desarrollo posterior en el lenguaje C++ de herramientas basadas en el paradigma de programación genérico [2] . Un concepto se puede declarar con cualquier tipo de plantilla ( clase de plantilla, plantilla de función o función de miembro de plantilla), su propósito es detectar inconsistencias lógicas entre las propiedades de los tipos de datos que se usan dentro del cuerpo de la plantilla y las propiedades de los datos. tipos que vienen en patrón como entradas [2] [3] .

Antes de su introducción en el lenguaje estándar, la noción de un concepto se implementó en la biblioteca de uso general de Boost en forma de clases de biblioteca BCCL ( Boost Concept Checking Library ) [4] .  

Sintaxis de la oración actual (de C++20)

Definición del concepto.

plantilla < claseT > _ concepto Igualdad Comparable () { requiere ( T a , T b ) { { a == b } -> Booleano ; // Un concepto que significa un tipo para convertir a booleano { a != b } -> Boolean ; }; }

Una plantilla que utiliza el concepto (tenga en cuenta que no hay una palabra clave de plantilla).

void f ( const Igualdad Comparable auto & );

Los conceptos intervendrán en la elección de qué función aplicar del conjunto de sobrecargas, junto con SFINAE . El compilador preferirá el concepto "más difícil".

Si usa el concepto en un inicializador, será similar a auto, pero el código se compilará si se admite el concepto.

Ordenable automáticamente x = f ( y ); // análogo de auto x = f(y), compilado si el resultado es un tipo adecuado para Sortable

Antecedentes

En la programación genérica, un concepto  es un conjunto de requisitos para un tipo para que el patrón de programación genérico tenga sentido. Por ejemplo, la plantilla asume dichas relaciones entre los tipos de iterador It1 e It2. It2 std::copy(It1, It1, It2)

  • It1 e It2 son iteradores unidireccionales.
  • La asignación es posible entre tipos *It2y .*It1

Estos conceptos se describen en la documentación de C++ y son una descripción verbal de las condiciones cuando se compila el código. Por ejemplo, si intenta especializar una plantilla con parámetros , el It1=int*, It2=int**compilador informará que la asignación no es posible int* ← int. Sin embargo, hay desventajas.

  • El error caerá en las profundidades del archivo de encabezado STL, en un código complejo que se sabe que es correcto.
  • A menudo, los textos de error son extremadamente detallados y es difícil averiguar qué es lo que falta exactamente para que la plantilla se especialice.
  • Cuando un programador escribe una plantilla, puede dejar accidentalmente el concepto y no notarlo. No hay forma de verificar esto excepto tratando de especializar la plantilla. En plantillas complejas, la "verificación de especialización" no es tan fácil como parece: la mayoría de los tipos más simples admiten muchas características adicionales. Por lo tanto, no es suficiente verificar std::vector<T>el tipo int: además de las operaciones "constructor sin parámetros", "mover constructor" y "asignar con mover", el mínimo requerido para un vector, un tipo entero tiene un constructor de copia, un operador de asignación, operaciones matemáticas y mucho más, y no hay garantías de que no se estén utilizando.

Además, hay que realizar funciones que aparecen o desaparecen en función de unas condiciones (conformidad o inconsistencia del concepto ). En C++17 , las plantillas para esto son complicadas.

Hasta el día de hoy, los conceptos solo se han descrito sintácticamente de forma limitada; por ejemplo, en Java , el papel de los conceptos lo desempeñan declaraciones como class Test <T extends Testable>.

Estado actual

Compilador Parcialmente Completamente
G++ 6 diez
MSVC 2019 No todavía
Sonido metálico diez No todavía

Notas

  1. ISO/IEC TS 19217:2015 . ISO (15 de noviembre de 2015). Consultado el 28 de abril de 2017. Archivado desde el original el 9 de diciembre de 2016.
  2. 1 2 3 Ostern M. G. Conceptos y modelado // Programación genérica y STL: uso y ampliación de la biblioteca de plantillas estándar de C++ = MH Austern. Programación Genérica y el STL. - San Petersburgo: Nevsky Dialect, 2004. - P.  32 . — 544 pág. - ISBN 5-7940-0119-4 .
  3. Siek J., Lee L.-Q., Lumsdaine A. 2.3 Conceptos y modelos // La biblioteca de gráficos Boost. Guía del usuario y Manual de referencia . - Addison-Wesley, 2002. - Pág  . 27 . — ISBN 0-201-72914-8 .
  4. Siek J., Lee L.-Q., Lumsdaine A. 2.5 Comprobación de conceptos // La biblioteca de gráficos Boost. Guía del usuario y Manual de referencia . - Addison-Wesley, 2002. - Pág  . 36 . — ISBN 0-201-72914-8 .