Ceci est une ancienne révision du document !
Table des matières
if
Conditions multiples sur une même valeur : fold (opérateur ...)
Avec les templates variadiques :
template <class T, class... Ts> constexpr bool isin(T&& val, Ts&&... arg) { // Toutes les parenthèses sont nécessaires. return ((arg == val) || ...); } int main() { if constexpr(isin(1, 0, 2, 3, 4, 5)) return 0; else return 1; }
C++ et les Fold Expressions Archive du 2016/11/27 le 05/01/2020
switch/case
Déclaration d'une variable dans un switch
Une variable définie dans un case
est accessible pour tous les case
le suivant. On ne peut donc définir dans un case
que des variables ayant un constructeur default
.
Il est donc conseillé de mettre des {}
entre chaque case
.
class A { public: A() = default; }; class B { public: B(){} }; int main() { int i = 0; switch (i) { case 0: // Valide car la classe A a un constructeur default. A a; // Non car si i vaut 1, le constructeur b ne sera pas appelé. // error: cannot jump from switch statement to this case label // B b1; break; case 1: { // Valide car b2 ne sera pas accessible en dehors de case 1. B b2; break; } case 2: default: break; } }
Sur un string
switch
ne fonctionne sur que les nombres. Pour utiliser un string, il faut passer par une fonction de hash (ici, djb2).
constexpr unsigned long djb2(char const *str) { unsigned long hash = 5381; int c = 0; while ((c = *str++)) hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ return hash; } int main() { std::string texte = "texte"; switch (djb2(texte.c_str())) { case djb2("texte"): texte = "OK"; break; } }
<note important>Toute création d'un hash présente un risque de collision.</note>
[[unlikely]] et [[likely]]
Il est possible d'indiquer au compilateur si une condition est généralement vraie ou fausse. Cela fonctionne sur if
et case
.
int i = 1; if (i == 1) [[likely]] ...
int f(int i) { switch(i) { case 1: return 1; [[likely]] case 2: return 2; [[unlikely]] default: return 3; } return 2; }
Code généré sans les attributs [[likely]]
et [[unlikely]]
.
gcc est utilisé et les options d'optimisation doivent être activées au minimum niveau 1.
f(int): mov eax, edi cmp edi, 1 je .L2 cmp edi, 2 mov edx, 3 cmovne eax, edx .L2: ret
Code généré avec les attributs [[likely]]
et [[unlikely]]
.
f(int): mov eax, edi cmp edi, 1 je .L2 cmp edi, 2 jne .L8 .L2: ret .L8: mov eax, 3 ret