Le principe de l'évolution est beaucoup plus rapide en informatique que chez le bipède.
Il est parfois utile de tester une constante avant la compilation d’un code. Imaginons que vous utilisiez une librairie et que vous vouliez être sûr que telle ou telle constante/enum/define est positive (pour un tableau etc..) par exemple.
Un mécanisme simple et pratique existe déjà mais pour les variables, il sagit des assertions (assert.h). Celle-ci interompent le programme si la condition n’est pas vérifiée.
L’equivalant statique (qui empèche la compilation si la condition n’est pas vérifiée) n’existe malheureusement pas nativement en C++, il va donc nous falloir trouver une feinte!
Tout va passer par une classe template spécialisée! Nous n’allons en effet que déclarer une classe template prenant un booléen en argument.
Puis nous spécialiserons directement la classe pour la valeure ‘true’ mais son l’implémentation pour la valeure ‘false’ n’existera pas.
Pour effectuer une assertion statique, nous n’aurons qu’à tenter d’instancier la classe avec la condition comme paramètre. Si la
condition n’est pas vérifiée (la valeure est égale à ‘false’) le code ne compilera pas car la classe est définit mais non-implémentée.
Laissons parler le code:
#include <assert.h> // On déclare une classe template qui n'aura que 2 valeure possible: // 'StaticAssert<true>' et 'StaticAssert<false>' // (line nous donnera la ligne de l'erreur si le compilo le veut bien) template<bool b, int line> class StaticAssert; // On implémente 'StaticAssert<true>' template<int line> class StaticAssert<true, line> { // classe vide }; // On n'implémente pas 'StaticAssert<false>', le code ne compilera donc pas // si cette version de la classe est instanciée. // Pour le style: // Mode release: #ifdef NDEBUG // Sans effet #define static_assert(x) ((void)0) // Mode debug: #else // Test: #define static_assert(x) StaticAssert<(x), __LINE__>() #endif // assertion dynamic #define dynamic_assert(x) assert(x) int main() { // une constante. const int I = 3; // NE COMPILE PAS static_assert(I < 2); return 0; }