OVH Cloud OVH Cloud

Surcharge de méthode

4 réponses
Avatar
Martinez Jerome
Bonjour,

Bon, quelques problemes de comprehension avec les surcharges de methodes
(sous Visual C++ 7) :

Dans un classe, prenons cet exemple, que je souhaite faire :

Class Test
{
Public :
Test (size_t HowMany, const _TCHAR Character); // 1
Test (const unsigned int Number, size_t Radix); // 2
};

J'essaye apres d'instancier avec :
Test A(1, 10);

En version non unicode (_TCHAR = char), pas de probleme : il passe par
la methode 2
En version unicode (_TCHAR = wchar_t), la boom :
"appel ambigu à une fonction surchargée"

Bon, ce n'est pas vraiment un probleme, je remplace les "size_t" par des
"int", et ca re-marche.

Mais je me pose la question sur le principe :
Est-il normal que le compilateur confonde un charactere (meme si il est
Unicode, donc 16 bits sur Win32) avec un size_t (donc unsigned int)
lorsqu'il doit convertir un int et a le choix entre les deux?
Et ce, seulement en Unicode.
Un charactere, c'est quand meme bien differentt d'un entier...

Tous les compilateurs font-il la meme chose?
Que dirait la norme la dessus?
Qu'est-ce qu'il ne faut pas faire lorsqu'on joue avec la surcharge de
methodes, afin qu'un utilisateur normal de la classe n'est jamais de
probleme d'appel ambigus?

Merci d'avance pour les reponses a ces questions métaphysique stupides :)

4 réponses

Avatar
Jean-Marc Bourguet
Martinez Jerome writes:

Bon, quelques problemes de comprehension avec les surcharges de methodes
(sous Visual C++ 7) :

Dans un classe, prenons cet exemple, que je souhaite faire :

Class Test
{
Public :
Test (size_t HowMany, const _TCHAR Character); // 1
Test (const unsigned int Number, size_t Radix); // 2
};

J'essaye apres d'instancier avec :
Test A(1, 10);

En version non unicode (_TCHAR = char), pas de probleme : il passe par la
methode 2


Ah, moi je trouve que c'est un probleme. J'aurais dit ambiguite.
Tiens, je ne suis pas le seul, sun CC, g++ et Como
(http://www.comeaucomputing.com/tryitout) sont d'accord avec moi, le
message de como:

"ComeauTest.c", line 20: error: more than one instance of overloaded
function "test" matches the argument list, the choices that match are:
function "test(size_t, character)"
function "test(unsigned int, size_t)"
The argument types that you used are: (int, int)
test(1, 10);
^

1 error detected in the compilation of "ComeauTest.c".

En version unicode (_TCHAR = wchar_t), la boom :
"appel ambigu à une fonction surchargée"


Je suis d'accord ici (comme les trois compilateurs que j'ai essaye),
nouveau message de gcc cette fois:
martinez.cc: In function `int main()':
martinez.cc:20: error: call of overloaded `test(int, int)' is ambiguous
martinez.cc:11: error: candidates are: void test(unsigned int, wchar_t)
martinez.cc:15: error: void test(unsigned int, unsigned int)

Ce qui se passe dans les deux cas: il y a deux int comme arguments,
aucune fonction ne correspond. Pour chacune d'entre elle, il faut
deux conversion, donc il n'y en a pas une meilleure que l'autres.

Bon, ce n'est pas vraiment un probleme, je remplace les "size_t" par
des "int", et ca re-marche.


A nouveau j'aurais dit ambiguite. Comme mes compilateurs. La seule
difference, c'est que cette fois-ci il n'y a qu'une conversion mais il
en faut a nouveau une pour chacune des fonctions.

Tous les compilateurs font-il la meme chose?


Non.

Que dirait la norme la dessus?


Mon interpretation est qu'il y a ambiguite.

Qu'est-ce qu'il ne faut pas faire lorsqu'on joue avec la surcharge
de methodes, afin qu'un utilisateur normal de la classe n'est jamais
de probleme d'appel ambigus?


Il faut mieux definir les surcharges de sorte qu'il y en ait une pour
chaque liste d'appel prevue.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Loïc Joly
Martinez Jerome wrote:

Bonjour,

Bon, quelques problemes de comprehension avec les surcharges de methodes
(sous Visual C++ 7) :

Dans un classe, prenons cet exemple, que je souhaite faire :

Class Test
{
Public :
Test (size_t HowMany, const _TCHAR Character); // 1
Test (const unsigned int Number, size_t Radix); // 2
};

J'essaye apres d'instancier avec :
Test A(1, 10);

En version non unicode (_TCHAR = char), pas de probleme : il passe par
la methode 2
En version unicode (_TCHAR = wchar_t), la boom :
"appel ambigu à une fonction surchargée"


En plus de la réponse de Jean-Marc, il me semble que par défaut, visual
C++ considère que wchar_t est un simple typedef à unsigned long (ce qui
est contraire à la norme), mais une option de compilation permet de
modifier ce comportement pour en faire un type à part.

--
Loïc

Avatar
Martinez Jerome
Loïc Joly wrote:

En plus de la réponse de Jean-Marc, il me semble que par défaut, visual
C++ considère que wchar_t est un simple typedef à unsigned long (ce qui
est contraire à la norme), mais une option de compilation permet de
modifier ce comportement pour en faire un type à part.



De ce que j'ai compris sous VC7 wchar_t est un simple typedef à unsigned
WORD, donc bloqué a 16 bits (et oui, pas d'UCS4 chez Microsoft :)), grrr ).
J'ai mis l'option de compilation pour que ce soit un vrai type, mais ca
ne change pas les messages d'erreurs

Merci a vous deux, je comprend que pour le compilateur, un entier n'est
pas considéré plus proche d'une entier non signé que d'un caractere (ce
qui est vraiment dommage car ca serait tres logique quand meme!)

Donc si je veux etre portable, j'evite ce genre de bétises :)

Avatar
kanze
Martinez Jerome wrote in
message news:<bntnns$...

[...]
Merci a vous deux, je comprend que pour le compilateur, un entier
n'est pas considéré plus proche d'une entier non signé que d'un
caractere (ce qui est vraiment dommage car ca serait tres logique
quand meme!)


Si C++ avait un type de caractère, peut-être ça serait logique. Mais C++
n'en a pas, pour diverses raisons (certaines historiques, mais d'autres
qui seraient à mon avis valid encore aujourd'hui et dans le cas où on
définissait un langage de zéro).

Donc si je veux etre portable, j'evite ce genre de bétises :)


En général, dès qu'il y a un surcharge avec un type entier, il est bon
d'en ajouter un avec int. Justement, pour éviter des ambiguïtés dans le
cas des constantes.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16