J’essayais de nettoyer un code qui utilise char*
avec std::ssortingng
et j’ai rencontré un problème illustré par le code suivant.
void Foo( int xIn , const std::ssortingng & fooIn ) { std::cout << "string argument version called \n"; } void Foo( int xIn , bool flagIn = true ) { std::cout << "bool argument version called \n"; } int main() { int x = 1; Foo( x , "testing" ); return 0; }
Lorsque je lance le programme, la version d’argument bool est appelée . Une conversion char*
to bool
préférable à char*
to const std::ssortingng&
ou est-ce que Visual Studio 2008 me joue des tours?
Aussi surprenant que soit ce comportement, le compilateur est conforme: la conversion char*
to bool
est préférable à la conversion en std::ssortingng
.
Lire la suite ici .
Les règles exactes sont énoncées dans la norme C ++. Ils sont étonnamment compliqués, mais le paragraphe suivant est crucial ici:
C ++ 11 13.3.3.2 Classement des séquences de conversion implicites [over.ics.rank]
2 Lors de la comparaison des formes de base des séquences de conversion implicites (telles que définies au 13.3.3.1), une séquence de conversion standard (13.3.3.1.1) est une meilleure séquence de conversion qu’une séquence de conversion définie par l’utilisateur ou une séquence de conversion en points de suspension.
char*
-to- bool
nécessite une “séquence de conversion standard” alors que char*
-to- ssortingng
nécessite une “séquence de conversion définie par l’utilisateur”. Par conséquent, le premier est préféré.
Ils correspondent tous les deux à une correspondance potentielle, mais le compilateur préfère la version bool
car une fonction de conversion fournie par l’utilisateur (ou, dans ce cas, par la bibliothèque) est requirejse.
Si vous voulez vraiment faire cela, fournir une surcharge pour const char*
peut vous aider:
void Foo( int xIn, const char* in) { return Foo( xIn, ssortingng(in) ); }
Je suppose qu’en faisant cela, il y a de très bonnes chances que le compilateur effectue un peu d’optimisation dessus.
Une solution simple serait de changer le bool
en int
– il existe une conversion implicite d’un pointeur en bool
, mais pas en int
. bool
to int
n’est pas un problème, donc le code existant qui passe bools continuera à fonctionner.
Malheureusement, cela affecte légèrement la lisibilité du code en masquant l’intention du paramètre.