introduction
constexpr
n'a pas été présenté comme un moyen de dire à l'implémentation que quelque chose peut être évalué dans un contexte qui nécessite une expression constante ; les implémentations conformes ont pu le prouver avant C ++ 11.
Quelque chose qu'une implémentation ne peut pas prouver, c'est l' intention d'un certain morceau de code:
- Qu'est-ce que le développeur veut exprimer avec cette entité?
- Faut-il autoriser aveuglément le code à être utilisé dans une expression constante , simplement parce que cela fonctionne?
De quoi le monde serait-il privé constexpr
?
Disons que vous développez une bibliothèque et réalisez que vous voulez pouvoir calculer la somme de chaque entier de l'intervalle (0,N]
.
int f (int n) {
return n > 0 ? n + f (n-1) : n;
}
Le manque d'intention
Un compilateur peut facilement prouver que la fonction ci-dessus peut être appelée dans une expression constante si l'argument passé est connu pendant la traduction; mais vous n'avez pas déclaré cela comme une intention - il se trouve que c'est le cas.
Maintenant, quelqu'un d'autre arrive, lit votre fonction, fait la même analyse que le compilateur; " Oh, cette fonction est utilisable dans une expression constante!" et écrit le code suivant.
T arr[f(10)]; // freakin' magic
L'optimisation
En tant que développeur de bibliothèque "génial" , vous décidez que f
le résultat devrait être mis en cache lors de son appel; qui voudrait calculer le même ensemble de valeurs encore et encore?
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];
}
Le résultat
En introduisant votre optimisation idiote, vous venez de rompre chaque utilisation de votre fonction qui se trouvait dans un contexte où une expression constante était requise.
Vous n'avez jamais promis que la fonction était utilisable dans une expression constante , et sans quoi constexpr
il n'y aurait aucun moyen de fournir une telle promesse.
Alors, pourquoi avons-nous besoin constexpr
?
L'utilisation principale de constexpr est de déclarer l' intention .
Si une entité n'est pas marquée comme constexpr
- elle n'a jamais été destinée à être utilisée dans une expression constante ; et même si c'est le cas, nous comptons sur le compilateur pour diagnostiquer un tel contexte (car il ne tient pas compte de notre intention).
constexpr
? Si oui, je peux voir une utilisation.