Methodenüberladung greift nicht bei Vererbung?



  • Hi,

    #include <iostream>
    #include <string>
    using namespace std;
    
    class A
    {
    public:
    	void foo(int) {cout << "A::foo";}
    };
    
    class B
    {
    public:
    	void foo(string) {cout << "B::foo";}
    };
    
    class C : public A, public B
    {
    };
    
    int main() {
    	C c;
    	c.foo(10);
    	c.foo("hi");
    	return 0;
    }
    

    In c.foo(10); wird wegen Uneindeutigkeit gemeckert, weil A::foo und B::foo in Frage kommen. Sind die Compiler hier nur doof oder gibt es einen triftigen Grund, wieso das nicht eindutig zugewiesen werden kann? Wenn der Grund eine Regel im Standard ist, was spräche dann dagegen die Überladung zur Auflösung der Uneindeutigkeit zu nutzen?


  • Mod

    Siehe [class.member.lookup]/(6.2). Bjarne hat es selbst begründet:

    In C++, there is no overloading across scopes - derived class scopes are not an exception to this general rule. (See D&E or TC++PL3 for details).

    Nimm einfach eine using declaration.



  • Okay, danke 🙂



  • Namensauflösung ist schon interessant. Ich habe das erst später richtig verstanden, wann der Compiler wo guckt. Scopes werden immer von innen nach außen durchsucht. Sobald aber etwas gefunden wurde, geht die Suche nicht mehr mit dem nächst höheren Scope weiter.

    Und dann gibt es noch das praktische Koenig-Lookup. Das läuft quasi fast immer zusätzlich.

    Man sollte auch wissen, dass using-Direktiven ( using namespace soundso ) ganz anders funktionieren als using-Deklarationen. using-Deklarationen führen Namen in dem Scope ein, wo die Deklarationen auftauchen. Bei using-Direktiven ist das nicht unbedingt der Fall. Die Namen aus soundso werden im "lokalsten" Namensraum injiziert, der sowohl den mit der using-Deklaration als auch soundso umfasst. Und das kann auch zu Mehrdeutigkeiten führen.


Log in to reply