samedi 16 septembre 2023

Accolades et std::optional

La nouvelle manière unifiée d'initialiser les valeurs en C++, c'est super. Bim, on met deux accolades, et on a gagné. Vraiment ?

Sur le papier, c'est bath, on peut pas se tromper:

int a = {};
std::string b = {};
std::optional<int> c = {};
MonObjectQuIlEstBeau d = {};

Sauf qu'il a danger ! C'est que lorsque l'on fait un changement de type quelque part, mettons un paramètre de fonction, et que l'on s'attend à ce que le compilo nous indique gentiment tous les endroits à changer, eh bien il est possible en fait que le compilo accepte le changement sans broncher, mais en changeant la sémantique. Et boum ! C'est ce qui m'est arrivé la semaine dernière, heureusement rapidement détecté. Voyez plutôt cet innocent programme, l'on a une fonction f qui prend un optionel, et on l'appelle en initialisant notre optionel sur vide.

#include <optional>

void f(std::optional<int> a);

int main()
{
    f({});
    return 0;
}

Un peu plus tard, l'on change la signature de f:

void f(int a);

Et boum, l'on initialise maintenant a avec la valeur 0, ce qui pourrait bien être complètement faux.

Que faire alors ? Eh bien, utilisons std::nullopt ! Ainsi, notre appel f(std::nullopt) fonctionnera correctement dans le premier cas, et causera une erreur de compilation dans le deuxième.

Conclusion : mangez du {}, mais avec les optionels, préférez std::nullopt !

Aucun commentaire: