Historique
C++ ne supportait initialement que les macros (#define) et les constantes (const). Cependant, pour définir des valeurs au moment de la compilation, cela n'était pas suffisant. En C++11, le mot-clé constexpr a été introduit, permettant de calculer des valeurs même au moment de la compilation, et non seulement lors de l'exécution du programme.
Problème
Avant l'apparition de constexpr, de nombreuses tâches devaient être résolues soit par des macros (un substitut de texte brut sans sécurité de type), soit par const, qui ne garantissait pas toujours l'exécution de l'expression au moment de la compilation. Cela compliquait l'optimisation du programme et conduisait à un comportement moins prévisible.
Solution
constexpr garantit au compilateur que l'expression déclarée sera nécessairement calculée au moment de la compilation, si cela est possible. Cela est utilisé pour déclarer des fonctions, des variables et même des constructeurs et des méthodes de classes qui peuvent être calculés de manière sûre et efficace au moment de la compilation.
Exemple de code :
constexpr int Square(int x) { return x * x; } constexpr int size = Square(5); // size est calculé au moment de la compilation const int arr[size] = {}; // peut être utilisé comme taille de tableau
Caractéristiques clés :
Peut-on utiliser n'importe quelle fonction comme constexpr ?
Non. La fonction doit respecter un certain nombre de contraintes : être suffisamment simple, contenir une seule instruction de retour (jusqu'à C++14) ou uniquement du code calculable de manière constante (à partir de C++14 et plus).
constexpr int f(int x) { return x + 2; } // ok constexpr int g(int x) { int y = x + 2; return y; } // jusqu'à C++14 : ne compile pas ! après — c'est possible
Toutes les variables constexpr peuvent-elles être calculées au moment de la compilation ?
Non. Si une valeur non constante est utilisée lors de l'initialisation ou si l'expression ne peut pas être calculée lors de la compilation, une erreur se produira.
int val; // constexpr int x = f(val); // Erreur : val n'est pas initialisé !
Quelle est la différence entre constexpr et const ?
const garantissant seulement l'impossibilité de modification, mais ne garantissant pas le calcul au moment de la compilation. constexpr exige que la valeur soit calculée au moment de la compilation (si possible).
const int x = time(nullptr); // ok, mais calculé au moment de l'exécution constexpr int y = 42; // ok, calculé au moment de la compilation
Un développeur utilise #define PI 3.14 pour tous les calculs de surface de cercle.
Avantages :
Inconvénients :
Un développeur utilise constexpr double PI = 3.141592653589793; et des fonctions constexpr modèles pour les calculs.
Avantages :
Inconvénients :