Il semble y avoir un consensus général sur l' accolade d'initialisation doit être privilégiée par rapport à d'autres formes d'initialisation, cependant, depuis l'introduction du C++17 extension globale de l'initialisation il semble y avoir un risque de non intentionnels des conversions. Considérons le code suivant:
struct B { int i; };
struct D : B { char j; };
struct E : B { float k; };
void f( const D& d )
{
E e1 = d; // error C2440: 'initializing': cannot convert from 'D' to 'E'
E e2( d ); // error C2440: 'initializing': cannot convert from 'D' to 'E'
E e3{ d }; // OK in C++17 ???
}
struct F
{
F( D d ) : e{ d } {} // OK in C++17 ???
E e;
};
Dans le code ci-dessus struct D
et struct E
représentent les deux complètement différents types. C'est donc une surprise pour moi que de C++17 il est possible de "convertir" d'un type vers un autre type sans aucun avertissement si vous utilisez corset (globale) de l'initialisation.
Que recommanderiez-vous pour éviter ces types d'accident conversions? Ou ai-je raté quelque chose?
PS: Le code ci-dessus a été testé dans Clang, GCC et la dernière VC++ - ils sont tous les mêmes.
Mise à jour: En réponse à la réponse de Nicol. Un exemple pratique:
struct point { int x; int y; };
struct circle : point { int r; };
struct rectangle : point { int sx; int sy; };
void move( point& p );
void f( circle c )
{
move( c ); // OK, makes sense
rectangle r1( c ); // Error, as it should be
rectangle r2{ c }; // OK ???
}
Je peux comprendre que vous pouvez afficher un circle
comme point
car circle
a point
comme classe de base, mais l'idée que vous pouvez en silence convertir à partir d'un cercle, un rectangle, pour moi, c'est un problème.
Mise à jour 2: Parce que mon mauvais choix de nom de la classe semble être opacification le problème pour certains.
struct shape { int x; int y; };
struct circle : shape { int r; };
struct rectangle : shape { int sx; int sy; };
void move( shape& p );
void f( circle c )
{
move( c ); // OK, makes sense
rectangle r1( c ); // Error, as it should be
rectangle r2{ c }; // OK ???
}