Introducción
constexpr
no se introdujo como una forma de decirle a la implementación que algo se puede evaluar en un contexto que requiere una expresión constante ; Las implementaciones conformes han podido probar esto antes de C ++ 11.
Algo que una implementación no puede probar es la intención de un cierto código:
- ¿Qué es lo que el desarrollador quiere expresar con esta entidad?
- ¿Deberíamos permitir ciegamente que el código se use en un expresión constante , solo porque funciona?
¿Sin qué sería el mundo constexpr
?
Digamos que está desarrollando una biblioteca y se da cuenta de que desea poder calcular la suma de cada número entero en el intervalo (0,N]
.
int f (int n) {
return n > 0 ? n + f (n-1) : n;
}
La falta de intención
Un compilador puede demostrar fácilmente que la función anterior es invocable en una expresión constante si el argumento pasado se conoce durante la traducción; pero no ha declarado esto como una intención, simplemente resultó ser el caso.
Ahora viene alguien más, lee tu función, hace el mismo análisis que el compilador; " ¡Oh, esta función es utilizable en una expresión constante!"y escribe el siguiente fragmento de código.
T arr[f(10)]; // freakin' magic
La optimizacion
Usted, como desarrollador de bibliotecas "impresionante" , decide que f
debe almacenar en caché el resultado cuando se invoca; ¿Quién querría calcular el mismo conjunto de valores una y otra vez?
int func (int n) {
static std::map<int, int> _cached;
if (_cached.find (n) == _cached.end ())
_cached[n] = n > 0 ? n + func (n-1) : n;
return _cached[n];
}
El resultado
Al presentar su tonta optimización, rompió cada uso de su función que estaba en un contexto donde una expresión constante se requería .
Nunca prometiste que la función fuera utilizable en una expresión constante , y sin ella constexpr
no habría forma de proporcionar esa promesa.
Entonces, ¿por qué necesitamos constexpr
?
El uso principal de constexpr es declarar intención .
Si una entidad no está marcada como constexpr
- nunca fue diseñada para usarse en una expresión constante ; e incluso si es así, confiamos en el compilador para diagnosticar dicho contexto (porque ignora nuestra intención).
constexpr
? Si es así, puedo ver un uso.