Étant donné une fonction très triviale,
int transform(int val) {
return (val + 7) / 8;
}
Il devrait être très évident qu'il est facile de transformer cette fonction en constexpr
fonction, ce qui me permet de l'utiliser lors de la définition de constexpr
variables, comme ceci:
constexpr int transform(int val) {
return (val + 7) / 8;
}
Mon hypothèse est qu'il s'agit strictement d'une amélioration, car la fonction peut toujours être appelée dans un non- constexpr
contexte, et elle peut maintenant également être utilisée pour aider à définir des variables constantes au moment de la compilation.
Ma question est, y a-t-il des situations où c'est une mauvaise idée? Par exemple, en faisant cette fonction constexpr
, puis-je jamais rencontrer une situation où cette fonction ne sera plus utilisable dans une circonstance particulière, ou où elle se comportera mal?
Réponses:
Cela n'a d'importance que si la fonction fait partie d'une interface publique et que vous souhaitez conserver les futures versions de votre API compatibles binaires. Dans ce cas, vous devez réfléchir soigneusement à la manière dont vous souhaitez faire évoluer votre API et à l'endroit où vous avez besoin de points d'extension pour les modifications futures.
Cela fait d'un
constexpr
qualificatif une décision de conception irrévocable. Vous ne pouvez pas supprimer ce qualificatif sans une modification incompatible de votre API. Cela limite également la façon dont vous pouvez implémenter cette fonction, par exemple, vous ne pourrez pas effectuer de journalisation dans cette fonction. Toutes les fonctions triviales ne resteront pas triviales dans l'éternité.Cela signifie que vous devriez utiliser de préférence
constexpr
des fonctions qui sont intrinsèquement des fonctions pures et qui seraient réellement utiles au moment de la compilation (par exemple pour la métaprogrammation de modèle). Il ne serait pas bon de rendre les fonctions constexpr simplement parce que l'implémentation actuelle se trouve être constexpr-able.Lorsque l'évaluation à la compilation n'est pas nécessaire, l'utilisation de fonctions en ligne ou de fonctions avec liaison interne semble plus appropriée
constexpr
. Toutes ces variantes ont en commun le fait que le corps de fonction est «public» et est disponible dans la même unité de compilation que l'emplacement d'appel.Si la fonction en question ne fait pas partie d'une API publique stable, cela pose moins de problème car vous pouvez modifier arbitrairement la conception à volonté. Mais puisque vous contrôlez maintenant tous les sites d'appels, il n'est pas nécessaire de marquer une fonction constexpr «juste au cas où». Vous savez si vous utilisez cette fonction dans un contexte constexpr. L'ajout de qualificatifs inutilement restrictifs pourrait alors être considéré comme une obfuscation.
la source
Marquer une fonction comme en
constexpr
fait également une fonction en ligne § [dcl.constexpr] / 1:inline
, à son tour, signifie que vous devez inclure la définition de cette fonction dans chaque unité de traduction dans laquelle elle peut être utilisée. Cela signifie essentiellement que lesconstexpr
fonctions doivent être soit:La plupart des fonctions typiques que vous souhaitez déclarer dans un en-tête et définir dans un fichier source (et tout autre élément qui les utilise inclut simplement l'en-tête, puis les liens avec le fichier objet de cette source)
constexpr
ne fonctionneront tout simplement pas.En théorie, je suppose que vous pouvez simplement tout déplacer dans les en-têtes et n'avoir qu'un seul fichier source qui inclut uniquement tous les en-têtes, mais cela nuirait considérablement aux temps de compilation, et pour la plupart des projets sérieux, il faudrait d'immenses quantités de mémoire pour compiler.
Une
constexpr
fonction est également limitée à certains égards, donc pour certaines fonctions, il peut ne pas être une option du tout. Les restrictions comprennent:constexpr
.try
bloc.J'ai sauté quelques choses plutôt obscures (par exemple, il ne peut pas non plus contenir de
goto
ou uneasm
déclaration), mais vous avez l'idée - pour pas mal de choses, cela ne fonctionnera tout simplement pas.Conclusion: oui, il y a pas mal de situations où ce serait une mauvaise idée.
la source