2016-10-26 3 views
6

Cela semble incohérent. J'ai 3 fonctions f surchargé pour les types signés short, int et long long. Si vous passez un unsigned short, il est promu au prochain type signé le plus grand: int. Cependant, si vous passez unsigned int alors il n'est pas promu à long long signé ce qui est ce que je m'attendais, plutôt compilateur se plaint de l'appel ambigu à la fonction surchargée.C++ appel ambigu à une fonction surchargée avec un entier non signé

void f(short x) { std::printf("f(short)\n"); } 
void f(int x) { std::printf("f(int)\n"); } 
void f(long long x) { std::printf("f(long long)\n"); } 

int main() 
{ 
    f((unsigned short)0); // Fine: calls f(int) 
    // f((unsigned int)0); // Ambiguous: could be f(short), f(int) or f(long long) 
} 
+0

Pourquoi vous attendriez-vous à cela et quelle est votre question? Pourquoi c'est comme ça? ou comment le rendre moins ambigu? – user463035818

+0

Oui, quelle est la justification? –

Répondre

6

Il est incompatible, oui, mais il est la façon dont la langue est, et vous devez faire face, par exemple si vous voulez f((unsigned int)0) appeler la surcharge long long, puis fournir une enveloppe,

inline void f(unsigned int x) { f((long long)x); } 

Les concepteurs de C++ auraient idéalement aimé faire vos deux cas échouent résolution de surcharge. Mais il y avait cette chose héritée (remontant à "K & R" C), appelée "default argument promotion", qui, essentiellement, dit que le compilateur convertira implicitement tous les types entiers plus étroits que int en int si nécessaire pour correspondre une signature de fonction, et tous les types à virgule flottante plus étroits que double à double idem.

Donc, c'est le cas f((unsigned short)0) qui est l'homme étrange, vraiment.

+0

Merci c'est instructif –

4

http://en.cppreference.com/w/cpp/language/implicit_conversion

promotion intégrale ne pas vous obtenez unsigned int-long long.

promotion intégrale ne vous obtenir de unsigned short à int.

La conversion intégrale de unsigned int est considérée comme tout aussi efficace pour vos surcharges.

Promotion se termine à int et/ou unsigned int à moins que votre type de source est un enum qui nécessite un type intégral plus grande pour l'adapter.

La promotion est préférée à la conversion, donc votre premier cas est sans ambiguïté. Dans le second cas, il n'y a pas de chemin de promotion, donc votre code est ambigu.