tipos teoria similitudes servicios servicio resumen restricciones productos producto principios pasos objetivos mercadotecnia mercado libro las features entre empresas ejemplos diferencias diferencia descargar definicion datos bien c++ c++11 d c++-concepts

c++ - similitudes - teoria de restricciones pasos



¿Cuáles son las diferencias entre conceptos y restricciones de plantilla? (3)

Quiero saber cuáles son las diferencias semánticas entre la propuesta de conceptos completos de C ++ y las restricciones de plantilla (por ejemplo, las restricciones que aparecen en Dlang o la nueva propuesta de conceptos-lite para C ++ 1y ).

¿Qué son capaces de hacer los conceptos completos que las limitaciones de la plantilla no pueden hacer?


La siguiente información está desactualizada. Debe actualizarse según el último borrador de Concepts Lite.

La Sección 3 de la propuesta de restricciones cubre esto en profundidad razonable.

La propuesta de conceptos se ha dejado en un segundo plano con la esperanza de que las limitaciones (es decir, conceptos-lite) puedan desarrollarse e implementarse en una escala de tiempo más corta, actualmente con el objetivo de al menos algo en C ++ 14. La propuesta de restricciones está diseñada para actuar como una transición suave hacia una definición posterior de conceptos. Las restricciones son parte de la propuesta de conceptos y son un bloque de construcción necesario en su definición.

En Design of Concept Libraries for C ++ , Sutton y Stroustrup consideran la siguiente relación:

Conceptos = Restricciones + Axiomas

Para resumir rápidamente sus significados:

  1. Restricción: un predicado sobre las propiedades evaluables estáticamente de un tipo. Requisitos puramente sintácticos. No es una abstracción de dominio.
  2. Axiomas: requisitos semánticos de los tipos que se supone que son verdaderos. No estático.
  3. Conceptos: requisitos generales y abstractos de algoritmos en sus argumentos. Definido en términos de restricciones y axiomas.

Entonces, si agrega axiomas (propiedades semánticas) a restricciones (propiedades sintácticas), obtiene conceptos.

Conceptos-Lite

La propuesta de los conceptos-lite nos trae solo la primera parte, las limitaciones, pero este es un paso importante y necesario hacia conceptos completamente desarrollados.

Restricciones

Las restricciones tienen que ver con la sintaxis . Nos dan una forma de propiedades estáticamente discernibles de un tipo en tiempo de compilación, de modo que podemos restringir los tipos utilizados como argumentos de plantilla en función de sus propiedades sintácticas. En la propuesta actual de restricciones, se expresan con un subconjunto de cálculo proposicional utilizando conectivos lógicos como && y || .

Echemos un vistazo a una restricción en acción:

template <typename Cont> requires Sortable<Cont>() void sort(Cont& container);

Aquí estamos definiendo una plantilla de función llamada sort . La nueva adición es la cláusula require . La cláusula require da algunas restricciones sobre los argumentos de la plantilla para esta función. En particular, esta restricción dice que el tipo Cont debe ser un tipo Sortable . Una cosa buena es que se puede escribir en una forma más concisa como:

template <Sortable Cont> void sort(Cont& container);

Ahora bien, si intentas pasar algo que no se considera Sortable a esta función, obtendrás un buen error que inmediatamente te dice que el tipo deducido para T no es un tipo Sortable . Si hubieras hecho esto en C ++ 11, hubieras tenido un error horrible dentro de la función de sort que no tiene sentido para nadie.

Los predicados de Restricciones son muy similares a los rasgos de tipo. Toman algún tipo de argumento de plantilla y le dan cierta información al respecto. Las restricciones intentan responder a los siguientes tipos de preguntas sobre el tipo:

  1. ¿Este tipo tiene tal o cual operador sobrecargado?
  2. ¿Se pueden usar estos tipos como operandos para este operador?
  3. ¿Este tipo tiene tal o cual rasgo?
  4. ¿Es esta expresión constante igual a eso? (para argumentos de plantilla sin tipo)
  5. ¿Este tipo tiene una función llamada yada-yada que devuelve ese tipo?
  6. ¿Este tipo cumple con todos los requisitos sintácticos para ser utilizado como tal?

Sin embargo, las restricciones no están destinadas a reemplazar los rasgos de tipo. En cambio, trabajarán mano a mano. Algunos rasgos de tipo ahora se pueden definir en términos de conceptos y algunos conceptos en términos de rasgos de tipo.

Ejemplos

Entonces, lo importante de las restricciones es que no les importa la semántica ni un ápice. Algunos buenos ejemplos de restricciones son:

  • Equality_comparable<T> : comprueba si el tipo tiene == con ambos operandos de ese mismo tipo.

  • Equality_comparable<T,U> : comprueba si hay == con operandos izquierdos y derechos de los tipos dados

  • Arithmetic<T> : comprueba si el tipo es de tipo aritmético.

  • Punto Floating_point<T> : comprueba si el tipo es de tipo coma flotante.

  • Input_iterator<T> : comprueba si el tipo admite las operaciones sintácticas que debe soportar un iterador de entrada.

  • Same<T,U> : verifica si el tipo dado es el mismo.

Puedes probar todo esto con una construcción especial de conceptos-lite de GCC .

Beyond Concepts-Lite

Ahora entramos en todo más allá de la propuesta de conceptos lite. Esto es incluso más futurista que el futuro en sí mismo. De aquí en adelante, todo cambiará bastante.

Axiomas

Los axiomas son semánticos . Especifican relaciones, invariantes, garantías de complejidad y otras cosas similares. Veamos un ejemplo.

Mientras que la restricción Equality_comparable<T,U> le dirá que hay un operator== que toma los tipos T y U , no le dice qué significa esa operación. Para eso, tendremos el axioma Equivalence_relation . Este axioma dice que cuando los objetos de estos dos tipos se comparan con operator== dando true , estos objetos son equivalentes. Esto puede parecer redundante, pero ciertamente no lo es. Podría definir fácilmente un operator== que en su lugar se comportó como un operator< . Serías malvado para hacer eso, pero podrías.

Otro ejemplo es un Greater axioma. Está muy bien decir que dos objetos de tipo T se pueden comparar con los operadores > y < , pero ¿qué significan ? El axioma Greater dice que si f x es mayor que y , entonces y es menor que x . La especificación propuesta tal axioma se ve así:

template<typename T> axiom Greater(T x, T y) { (x>y) == (y<x); }

Entonces los axiomas responden los siguientes tipos de preguntas:

  1. ¿Estos dos operadores tienen esta relación entre ellos?
  2. ¿Este operador para tal y tal tipo significa esto?
  3. ¿Esta operación en ese tipo tiene esta complejidad?
  4. ¿Este resultado de ese operador implica que esto es cierto?

Es decir, están preocupados por completo con la semántica de tipos y operaciones en esos tipos. Estas cosas no se pueden verificar estáticamente. Si esto debe verificarse, un tipo debe proclamar de alguna manera que se adhiere a esta semántica.

Ejemplos

Aquí hay algunos ejemplos comunes de axiomas:

  • Equivalence_relation : si dos objetos se comparan == , son equivalentes.

  • Greater : Siempre que x > y , entonces y < x .

  • Less_equal : Siempre que x <= y , entonces !(y < x) .

  • Copy_equality : para y de tipo T : si x == y , un nuevo objeto del mismo tipo creado por la construcción de copia T{x} == y aún x == y (es decir, no es destructivo) .

Conceptos

Ahora los conceptos son muy fáciles de definir; son simplemente la combinación de restricciones y axiomas . Proporcionan un requisito abstracto sobre la sintaxis y la semántica de un tipo.

Como ejemplo, considere el siguiente concepto Ordered :

concept Ordered<Regular T> { requires constraint Less<T>; requires axiom Strict_total_order<less<T>, T>; requires axiom Greater<T>; requires axiom Less_equal<T>; requires axiom Greater_equal<T>; }

En primer lugar, tenga en cuenta que para la plantilla tipo T que se Ordered , también debe cumplir los requisitos del concepto Regular . El concepto Regular es un requisito muy básico para que el tipo se comporte bien: se puede construir, destruir, copiar y comparar.

Además de esos requisitos, el Ordered requiere que T cumpla una restricción y cuatro axiomas:

  • Restricción: un tipo Ordered debe tener un operator< . Esto está comprobado estáticamente por lo que debe existir.
  • Axiomas: para y de tipo T :
    • x < y da un orden total estricto.
    • Cuando x es mayor que y , y es menor que x , y viceversa.
    • Cuando x es menor o igual a y , y no es menor que x , y viceversa.
    • Cuando x es mayor que o igual a y , y no es mayor que x , y viceversa.

La combinación de restricciones y axiomas como este te da conceptos. Definen los requisitos sintácticos y semánticos para los tipos abstractos para su uso con algoritmos. Los algoritmos actualmente tienen que suponer que los tipos utilizados admitirán ciertas operaciones y expresarán cierta semántica. Con conceptos, podremos garantizar que se cumplan los requisitos.

En el último diseño de conceptos , el compilador solo verificará que los requisitos sintácticos de un concepto se cumplan mediante el argumento de la plantilla. Los axiomas se dejan sin marcar. Dado que los axiomas denotan semántica que no es evaluable estadísticamente (o que a menudo es imposible verificar por completo), el autor de un tipo debería declarar explícitamente que su tipo cumple con todos los requisitos de un concepto. Esto se conocía como mapeo de conceptos en diseños previos, pero desde entonces se ha eliminado.

Ejemplos

Aquí hay algunos ejemplos de conceptos:

  • Regular tipos Regular son constructables, destructibles, copiables y se pueden comparar.

  • Ordered tipos pedidos soportan operator< , y tienen un orden total estricto y otra semántica de ordenamiento.

  • Copyable tipos que se pueden copiar son Copyable , destruibles, y si x es igual a Copyable se copia, la copia también se comparará igual a y .

  • Iterator tipos de Iterator deben tener tipos asociados value_type , reference , difference_type e value_type , que a su vez deben cumplir ciertos conceptos. También deben ser compatibles con el operator++ y ser eliminatorios.

El camino hacia los conceptos

Las restricciones son el primer paso hacia una característica de conceptos completos de C ++. Son un paso muy importante, ya que proporcionan los requisitos de los tipos de forma estática para que podamos escribir clases y funciones de plantillas mucho más claras. Ahora podemos evitar algunas de las dificultades y std::enable_if de std::enable_if y sus amigos de metaprogramación.

Sin embargo, hay una serie de cosas que la propuesta de restricciones no hace:

  1. No proporciona un lenguaje de definición de conceptos.

  2. Las restricciones no son mapas conceptuales. El usuario no necesita anotar específicamente sus tipos para cumplir ciertas restricciones. Se controlan estáticamente y se utilizan funciones de lenguaje de tiempo de compilación simple.

  3. Las implementaciones de plantillas no están limitadas por las restricciones en sus argumentos de plantilla. Es decir, si su plantilla de función hace algo con un objeto de tipo restringido que no debería hacer, el compilador no tiene forma de diagnosticar eso. Una propuesta de conceptos con todas las funciones podría hacer esto.

La propuesta de restricciones se ha diseñado específicamente para que se pueda introducir una propuesta de conceptos completos en la parte superior. Con un poco de suerte, esa transición debería ser un viaje bastante suave. El grupo de conceptos busca introducir restricciones para C ++ 14 (o en un informe técnico poco después), mientras que los conceptos completos podrían comenzar a surgir en algún momento alrededor de C ++ 17.


Mis 2 centavos:

  1. La propuesta de conceptos-lite no pretende hacer una "verificación de tipos" de la implementación de plantillas. Es decir, Concepts-lite garantizará (en teoría) la compatibilidad de la interfaz en el sitio de creación de instancias de la plantilla. Citando del artículo: "conceptos lite es una extensión de C ++ que permite el uso de predicados para restringir argumentos de plantilla". Y eso es. No dice que el cuerpo de la plantilla se verificará (de forma aislada) frente a los predicados. Eso probablemente significa que no hay una noción de primera clase de los arquetipos cuando se habla de conceptos lite. Los arquetipos, si mal no recuerdo, en los conceptos -propuestas pesadas- son tipos que ofrecen no menos y no más para satisfacer la implementación de la plantilla.

  2. Los conceptos-lite utilizan funciones constexpr glorificadas con un poco de truco de sintaxis respaldado por el compilador. Sin cambios en las reglas de búsqueda.

  3. Los programadores no están obligados a escribir mapas de conceptos.

  4. Finalmente, citando nuevamente "La propuesta de restricciones no aborda directamente la especificación o el uso de la semántica, sino que está dirigida solo a verificar la sintaxis". Eso significaría que los axiomas no están dentro del alcance (hasta ahora).