2016-06-08 17 views
5

Ich habe das folgende Stück Code:Warum Compiler siehe Methode der Basisklasse nicht, wenn CRTP mit

struct Iface 
{ 
    virtual int Read() = 0; 

    int Read(int x) { 
     return Read() + x; 
    } 
}; 

template <typename Impl> 
struct Crtp : public Iface 
{ 
    virtual int Read() { 
     return static_cast<Impl&>(*this).ReadImpl(); 
    } 
    //using Iface::Read; 
}; 

struct IfaceImpl : public Crtp<IfaceImpl> 
{ 
    int ReadImpl() { 
     return 42; 
    } 
}; 

int main() 
{ 
    IfaceImpl impl; 
    impl.Read(24); // compilation error 

    Iface& iface = impl; 
    iface.Read(24); // always compiles successfully 
} 

Sowohl msvc, gcc und Klirren diesen Code ablehnen, können sie nicht Methode Read(int x)

Allerdings finden Wenn ich using Iface::Read in auskommentiere, kompiliert mein Code erfolgreich.

Beachten Sie, dass, wenn ich einen Verweis auf Iface nehme ich anrufen kann Read(int x)

Warum ist das passiert?

Antwort

7

Warum passiert das?

Ihr Problem hat nichts mit CRTP zu tun. Es ist ein Problem, das das Verbergen von Namen in einem normalen Vererbungsszenario verhindert. Wenn Sie impl.Read(24); aufrufen, kann der Mitgliedsfunktionsname Read nicht im Klassenbereich IfaceImpl gefunden werden. Dann wird der Umfang der Basisklasse untersucht und dort der Name Read gefunden. Dann stoppt die Namensuche, so dass int Read(int x) in der weiteren Basisklasse Iface für die Überladungsauflösung nicht berücksichtigt wird, obwohl dies hier sinnvoller ist.

Durch using Iface::Read; führen Sie den Namen Read in den Klassenbereich von ein. Dann könnte es durch Überladungsauflösung korrekt gefunden und ausgewählt werden.

Und wenn Sie es über Iface Verweis aufrufen, wird der Name Lookup gut funktionieren.

Oder Sie können es explizit (und hässlich) von impl.Iface::Read(24); nennen.

Siehe Unqualified name lookup:

... Namenssuche die Bereiche untersucht, wie unten beschrieben, bis sie zumindest eine Erklärung aller Art findet, zu welchem ​​Zeitpunkt die Suche beendet und keine weiteren Bereiche untersucht werden.