2012-09-07 23 views
23

Estaba viendo la clase std::ratio<> del estándar C++ 11 que permite hacer aritmética racional en tiempo de compilación.Principios de diseño detrás de std :: ratio <>

Encontré el diseño de la plantilla y las operaciones implementadas con clases demasiado complejas y no encontré ninguna razón por la cual no pudieran usar un enfoque más sencillo e intuitivo implementando una clase racional realmente simple y definiendo las funciones constexpr para los operadores. El resultado hubiera sido una clase más fácil de usar y las ventajas del tiempo de compilación se habrían mantenido.

¿Alguien tiene alguna idea de las ventajas del diseño actual std::ratio<> en comparación con una implementación de clase simple utilizando constexpr? En realidad, no puedo encontrar ninguna ventaja en la implementación actual.

+4

http://www.joelonsoftware.com/articles/fog0000000018.html –

+0

¿No es el tiempo de compilación (por lo tanto, plantillas) frente al tiempo de ejecución? – Drakosha

+4

@Drakosha: 'constexpr' no es una pista; en ciertos contextos (donde se requiere una expresión constante), un compilador * debe * ejecutarlos en tiempo de compilación. –

Respuesta

36

Cuando se propuso N2661, ninguno de los autores de la propuesta tuvo acceso a un compilador que implementó constexpr. Y ninguno de nosotros estuvo dispuesto a proponer algo que no pudimos construir y probar. Entonces, si un diseño mejor podría haberse hecho con constexpr ni siquiera era parte de la consideración del diseño. El diseño se basó solo en aquellas herramientas disponibles para los autores en ese momento.

+0

Por supuesto que vendría con una respuesta tan práctica. : -] – ildjarn

+4

@ jon34yp: interesante que resulta que el que pregunta ha hecho dos preguntas: (1) ¿Cuáles fueron los principios de diseño detrás de 'std :: ratio', sobre qué tema creo que Howard es una autoridad. (2) ¿Cuáles son las ventajas del diseño actual, que podría tener todo tipo de respuestas de las cuales Howard no está consciente, sin haberlo considerado nunca :-) –

0

std::ratio y sus mecanismos circundantes siempre se ejecutarán en tiempo de compilación, en virtud de metaprogramación de plantillas y manipulación de tipos. constexpr solo se requiere para ejecutarse en tiempo de ejecución cuando las instalaciones de C++ requieren una expresión constante (tales como parámetros de plantilla o inicialización de una variable constexpr).

¿Qué es más importante para usted: la ejecución en tiempo de compilación, o ser "más directo e intuitivo"?

+3

Con 'constexpr', podemos tener tanto el uso intuitivo como la ejecución en tiempo de compilación para expresiones constantes, con las mismas expresiones exactas que las plantillas. Entonces, ambas ventajas a la vez parecen más bien un comercio justo. – Morwenn

+2

@Morwenn: Lo que intenta hacer Nicol es que si usas un 'constexpr' en una situación en la que no es necesario (digamos una expresión regular dentro de una función) el' constexpr' puede o no evaluarse en tiempo de compilación, es decir, podría desencadenar una llamada de función en tiempo de ejecución. También tenga en cuenta que las funciones que son 'constexpr' solo pueden usar un subconjunto del lenguaje, por lo tanto, es posible que no den como resultado un diseño tan natural. –

+3

@David: puede forzar una función 'constexpr' en otro contexto para ser evaluada en tiempo de compilación, usando trucos como' plantilla struct compile_time_dammit {enum {value = N}; }; ... compile_time_dammit :: value; '. Todo lo cual es discutible ya que la respuesta a la pregunta no tiene nada que ver con los pros y los contras de 'constexpr' :-) –

13

La solución constexpr resuelve un problema completamente diferente. std::ratio fue creado para ser utilizado como un puente entre las variables que usan diferentes unidades, no como una herramienta matemática. En estas circunstancias, es absolutamente necesario que la relación sea parte del tipo. La solución constexpr no funcionará allí. Por ejemplo, no será posible implementar std::duration sin un espacio de tiempo de ejecución y costos de tiempo de ejecución, ya que cada objeto de duración necesitaría llevar su información nominador/denominador dentro del objeto.

+0

Lo mismo ocurre con una biblioteca razonable de en la que desearía potencias fraccionarias de varias dimensiones, pero usted a) no querría transportar alrededor de tres o cinco fracciones reales yb) desea que dist + time sea un error de tipo compilador, no un error de tiempo de ejecución. – emsr

Cuestiones relacionadas