2015-05-02 8 views
5

Das ist mein Snippet:Warum wird eine fehlerhafte Funktion anstelle einer impliziten Konvertierung verwendet?

class Base{}; 

class Derived : private Base{}; 

template<class T> 
class Wrapper 
{ 
    public: 
     template<typename T2> 
     Wrapper(T2&&) 
     { } 
}; 

// Function declarations 
void func(Base& param); 
void func(Wrapper<Derived>); 
void funcUnambiguous(Wrapper<Derived>); 


// Here is the Call: 
Derived d = Derived(); 
func(d);    // <- Error 

GCC 4.9 gibt mir: error: 'Base' is an inaccessible base of 'Derived'

Während ich

Derived d = Derived(); 

funcUnambiguous(d); 

tun es funktioniert gut.

Es scheint so, als ob jede Funktion, die nur einen billigen Cast erfordert, selbst wenn sie fehlerhaft ist, implizite, aber kostspielige Funktionen versteckt. Hat jemand eine Ahnung?

Antwort

5

Aktualisiert, dank @ T.C.

Wrapper ‚s Ctor ist eine Vorlagebenutzerdefinierte Umwandlung, daher die Nicht-TemplateStandardkonvertierungssequenz Überlast mit Base& Vorrang hat. Die Zugangskontrolle wird nur durchgeführt nach Auswahl der Überlast - was zu spät ist in Ihrem Fall.

Die vollständigen Regeln sind kompliziert, mehr können here gefunden werden, schauen Sie sich den Abschnitt "Beste lebensfähige Funktion" an.

+0

Selbst wenn falsch ?! Das macht nicht wirklich Sinn, besonders in diesem Fall, wo die Basisklasse explizit "privat" gemacht wird. –

+0

Ich sehe, aber ist das nicht ein Fehler im Standard? Es gibt KEINE implizite Konvertierung, nicht einmal eine explizite. Danke trotzdem! –

+0

@JakobRiedle Die Überladungsauflösung ist einer der kompliziertesten Teile von C++ (IMHO). Ich wage nicht einmal zu denken, dass ich alle Regeln in allen Fällen kenne, dass ich weiß, was "richtig" oder sogar "besser" ist oder wie sich alles im Laufe der Zeit entwickelt hat. :) Ich denke, wir müssen es einfach so akzeptieren, wie es ist. –