2010-11-06 35 views
12

Tenir compte de la classe foo avec deux constructeurs définis comme ceci:Pourquoi existe-t-il une conversion de type implicite des pointeurs vers bool en C++?

class foo 
{ 
public: 
    foo(const std::string& filename) {std::cout << "ctor 1" << std::endl;} 
    foo(const bool some_flag = false) {std::cout << "ctor 2" << std::endl;} 
}; 

instancier la classe avec une chaîne littérale, et devinez quel constructeur est appelé?

foo a ("/path/to/file"); 

Sortie:

cteur 2

Je ne sais pas pour vous, mais je ne trouve pas que le comportement le plus intuitif dans l'histoire de la programmation. Je parie qu'il y a une raison intelligente pour cela, et j'aimerais savoir ce que cela pourrait être?

+2

duplication possible de [Pourquoi le compilateur a-t-il choisi une chaîne de caractères pour le modèle implicite de L ""?] (Http://stackoverflow.com/questions/316181/why-does-the-compiler-choose-bool-over -string-for-implicit-typecast-of-l) – Hasturkun

+2

Encore une autre question similaire: [Fonction/Méthode de surcharge C++: confusion de type de données?] (http://stackoverflow.com/questions/1636181/function-method-overloading- c-data-type-confusion) – Athari

+0

Désolé. J'ai fait une recherche (comme je me suis dit que ce serait une FAQ), mais je n'ai pas trouvé de questions avec un titre qui impliquait que la question était à ce sujet. – Oystein

Répondre

9

Il est très fréquent en C pour écrire ce

void f(T* ptr) { 
    if (ptr) { 
     // ptr is not NULL 
    } 
} 

Vous devriez faire un constructeur const char*.

+7

Vous voulez certainement dire 'if (! Ptr) return;'? :) Nous ne voudrions pas que notre fonction entière soit imbriquée de bloc plus que nécessaire. – GManNickG

+3

@GMan: Je dois vraiment * défendre * ce genre de déclaration de retour, parce que les pouvoirs qui ont été décidés que plusieurs déclarations de retour étaient intrinsèquement déroutantes et difficiles à suivre, et ont ancré cette croyance dans les normes de codage. – Cascabel

+2

Je voudrais upvote ceci, si elle ne recommanderait pas un paramètre 'char *':/ –

1

Vous êtes en train de créer deux problèmes. L'un est que "blah" peut être implicitement converti en string et l'autre est que const char* peut être implicitement converti en un booléen. Il est très logique de voir le compilateur aller à la conversion implicite qui minimise le nombre total de conversions nécessaires.

+0

Je donnais juste un exemple que je pensais être commun à rencontrer - ma question était _why_ la conversion de type implicite en 'bool' se produit avec des pointeurs. – Oystein

2

Vous passez un caractère * au constructeur foo. Cela peut être implicitement converti en un booléen (comme tous les pointeurs) ou en un std :: string. Du point de vue du compilateur, la première conversion est "plus proche" que la seconde car elle favorise les conversions standard (c'est-à-dire pointeur vers bool) sur les conversions fournies par l'utilisateur (le constructeur std :: string (char *)).