Outils pour utilisateurs

Outils du site


lang:cpp:condition

if

Les if peuvent s'optimiser avec les attributs unlikely et likely.

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

Les switch/case peuvent s'optimiser avec les attributs unlikely et likely.

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;
  }
}

Toute création d'un hash présente un risque de collision.

lang/cpp/condition.txt · Dernière modification : 2020/06/16 15:15 de root