Implizite Typumwandlung im Methodenaufruf



  • Hallo zusammen,
    ich versuche gerade nachzuvollziehen, wie die implizite Typumwandlung in C++ funktioniert. Dazu habe ich mir folgendes Testprogramm aufgebaut:

    #include <iostream.h>
    class A
    {public:
    		void typ(char x, char y, char z) {cout<<"CCC"<<endl;}
    		void typ(char x, char y, float z) {cout<<"CCF"<<endl;}
    		void typ(int x, float y, float z) {cout<<"IFF"<<endl;}
    		void typ(float x, char y, float z) {cout<<"FCF"<<endl;}
    		void typ(int x, int y, int z) {cout<<"III"<<endl;}};
    int main()
    {	char s='e'; int i=3; float f=4; A a;
    	a.typ(s,s,s); //1
    	a.typ(s,f,f); //2
    	a.typ(f,f,f); //3
    	a.typ(i,s,f); //4
    	a.typ(f,i,s); //5
    	a.typ(f,f,i); //6
    	a.typ(s,i,f); //7
    	a.typ(f,s,i); //8
    	a.typ(s,i,i); //9
    	a.typ(s,f,i); //10}
    

    Ergebnis: Nur der erste Aufruf mit s,s,s wird akzeptiert. Alle anderen rufen eine Fehlermeldung hervor ("call of overloaded 'typ...' is ambiguous")
    Meiner Meinung nach müssten aber Aufruf 4, 8 und 10 ebenfalls klappen.

    Kann mit jemand erklären, wo mein Denkfehler liegt?

    Vielen Dank im Voraus!
    Philip



  • PhilipM schrieb:

    Meiner Meinung nach müssten aber Aufruf 4, 8 und 10 ebenfalls klappen.

    Ich sehe jetzt keinen Grund warum 4,8 und 10 funktionieren sollten - Es muss auf jedenfall mindestens eine Umwandlung gemacht werden, und dann ist immer die Frage: welche Funktion soll genommen werden?

    cu André


  • Mod

    #include <iostream>
    void foo(char,  char,  char)  { std::cout << "CCC\n"; }
    void foo(char,  char,  float) { std::cout << "CCF\n"; } 
    void foo(int,   float, float) { std::cout << "IFF\n"; }
    void foo(float, char,  float) { std::cout << "FCF\n"; }
    void foo(int,   int,   int)   { std::cout << "III\n"; }
    
    int main()
    {
        char c='e';
        int i=3;
        float f=4;
    // 0 = exact match
    // 1 = promotion ( char->int )
    // 2 = conversion ( char->float, int->float, float->char, float->int )
        foo( c, c, c ); //  1 CCC(000) ccf(002) iff(122) fcf(202) iii(111)
        foo( c, f, f ); //  2 CCC(022) CCF(020) IFF(100) FCF(220) III(122)
        foo( f, f, f ); //  3 ccc(222) ccf(220) IFF(200) FCF(020) iii(222)
        foo( i, c, f ); //  4 CCC(202) CCF(200) IFF(020) FCF(200) III(012)
        foo( f, i, c ); //  5 CCC(220) CCF(222) IFF(222) FCF(022) III(201)
        foo( f, f, i ); //  6 ccc(222) ccf(222) IFF(202) FCF(022) III(220)
        foo( c, i, f ); //  7 CCC(022) CCF(020) IFF(120) FCF(220) III(102)
        foo( f, c, i ); //  8 CCC(202) CCF(202) iff(222) FCF(002) III(210)
        foo( c, i, i ); //  9 CCC(022) CCF(022) iff(122) fcf(222) III(100)
        foo( c, f, i ); // 10 CCC(022) CCF(022) IFF(102) fcf(222) III(120)
    }
    

    Eine Überladung ist besser als eine andere Überladung für ein gegebenes Argumenttupel, wenn der Konvertierungsrang für kein Argument schlechter (also wie oben definiert numerisch größer) als der Rang für dieses Argument für die andere Überladung ist, und der Rang für wenigstens ein Argument besser ist. Mithin sind oben alle möglichen Kombinationen mit Konvertierungsrang angegeben. Die jeweilige Überladung wird klein geschrieben, wenn sie schlechter als alle großgeschriebenen Überladungen ist. Eine Mehrdeutigkeit besteht immer dann, wenn mehr als eine Überladung groß geschrieben werden muss - dann gibt es mehrere "beste" Überladungen.



  • Genau - eine Umwandlung muss gemacht werden. Allerdings kann ja z.B. von float keine implizite Umwandlung auf int geschehen. Implizite Umwandlung heißt doch, dass ich z.B. schreiben kann:

    char c = 'e';
    int i = c;
    

    c wird dann auf int "erweitert".

    Jetzt zurück zum Beispiel: In Aufruf 8 (f,s,i) kann i nach float geweitet werden, so dass die vierte Überladung von "typ" passt. Bei allen anderen Überladungen ist es jedoch nicht möglich - also keine Zweideutigkeit. 😕



  • @camper: Vielen Dank für die ausführliche Antwort. Mir war nicht klar, dass C++ einen solchen Vergleich anstellt. Bin davon ausgegangen, dass eine Überladung auch dann auf jeden Fall besser ist als eine andere, wenn sie weniger Typumwandlungen durchführt als die andere.

    Danke!


Anmelden zum Antworten