2010-11-13 12 views
1

Voici la situation:g ++ me donne appel de fonction étrange dans un * prévu * message d'erreur

void funct(unsigned u, double d, float f) 
{ 
     u = 12; 
} 
void funct(double u, int d, void* asd, float f) 
{ 
     u = 13; 
} 

int main() 
{ 
     const unsigned u = 123; 
     double d = 123.123; 
     float f = 123.123; 

     funct(u, d, f, 123); 

     return 0; 
} 

me donne:

./src/test.cpp:19: error: no matching function for call to 'funct(const unsigned int&, double&, float&, int)' 
./src/test.cpp:4: note: candidates are: void funct(unsigned int, double, float) 
./src/test.cpp:8: note:     void funct(double, int, void*, float)

Il est absolument erreur attendue, car il n'y a pas de fonction appropriée à appeler , OK bien. Mais jetez un oeil à l'erreur du compilateur:

              V  V  V 
no matching function for call to 'funct(const unsigned int&, double&, float&, int) 

Pourquoi ces & là? Quand je fais un appel correct - tout va bien, et tous les paramètres, comme prévu, ne sont pas passés en tant que références.

En utilisant Ubuntu 10.04, et 64bit g++ version 4.4.3

+0

FWIW, [Comeau] (http://www.comeaucomputing.com/tryitout/) dit 'aucune instance de fonction surchargée correspond à "de fonct"(const unsigned int , double, float, int) '. (J'ai découpé beaucoup de texte pour le rendre lisible dans un commentaire.) – sbi

Répondre

4

vous passez une variable réelle qui peut être attribué à (un "lvalue") à la fonction. Bien sûr, vous le passez en valeur, pas par référence - mais le point est, dans votre fonction, vous appelez serait également de le passer aussi par référence, parce que c'est un lvalue.

Puis: Si vous avez une valeur de type int& (lvalue), vous êtes autorisé à envoyer à une fonction qui accepte int (soit rvalue ou lvalue) - tout simplement pas l'inverse.

4

Le compilateur ne sait pas si vous avez l'intention de transmettre vos variables par valeur ou par référence. Il ne peut pas exclure la possibilité que la fonction correcte (celle que vous avez omis de déclarer) attend des références.

0

Il essaie de mapper les expressions d'argument pour les exprimer uniquement en termes de types. Donc pour les lvalues ​​de type T, il utilise T&, et pour les valeurs de type T il utilise T (non modifié).

Bien sûr, une expression d'argument n'a jamais de type de référence (aucune expression ne peut avoir de type de référence), mais c'est la façon dont GCC exprime cela. Pour C++ 0x, il y aura lvalues, xvalues ​​et prvalues. GCC utiliserait probablement T& pour le premier et T pour les deux derniers, ou T&& pour le second et T pour le dernier.

Clang fait un meilleur travail ici

main1.cpp:16:9: error: no matching function for call to 'funct' 
     funct(u, d, f, 123); 
     ^~~~~ 
main1.cpp:5:6: note: candidate function not viable: no known conversion from 'float' to 
        'void *' for 3rd argument          
void funct(double u, int d, void* asd, float f) 
    ^
main1.cpp:1:6: note: candidate function not viable: requires 3 arguments, but 4 were provided 
void funct(unsigned u, double d, float f) 
    ^
1 error generated.