Fehler invalid covariant return type (nur bei GCC)



  • Hallo,

    bin gerade dabei, von Visual Studio (2015) auf GCC umzusteigen. Folgender Code wird vom VS Compiler compiliert, vom GCC jedoch nicht (getestet wurden gcc 4.8 und gcc 6.1)

    class ControlObject {
    };
    
    class Endpoint {
    	virtual ControlObject* getParent() = 0;
    };
    
    template <class CO>
    class SimpleEndpoint: public Endpoint {
    	virtual CO* getParent() override {
    		return nullptr; //Dummy impl
    	}
    };
    
    class Joint: public ControlObject, public SimpleEndpoint<Joint> {
    };
    

    GCC meldet mir

    error: invalid covariant return type for ‘CO* SimpleEndpoint<CO>::getParent() [with CO = Joint]
    

    Meiner Meinung nach ist dieser vollkommen korrekt, denn 'Joint' ist auch ein 'ControlObject' und somit auch ein gültiges Covariant return type für 'ControlObject' in getParent().

    Ist das ein Bug vom GCC oder eine Erweiterung von VS C++?

    Viele Grüße



  • Es ist eine Erweiterung oder ein Bug von VS. Während SimpleEndpoint<Joint> instantiiert wird, gilt Joint nur als deklariert, nicht definiert. Insbesondere ist es dann ein unvollständiger Typ und keine abgeleitete Klasse.
    Vgl:

    #include <iostream>
    #include <type_traits>
    
    class A { };
    
    template <typename T, typename En = void>
    class C : public std::false_type { };
    
    template <typename T>
    class C<T, std::enable_if_t<std::is_base_of<T, A>::value>> : public std::true_type { };
    
    class B : public A, public C<B> { };
    
    int main() { 
    	std::cout << std::boolalpha << C<B>::value << '\n';
    }
    


  • Danke für die schnelle Antwort!

    Dein Code verhält sich aber tatsächlich auf beiden Systemen gleich, es wird also nicht die Spezialisierung genommen und dementsprechend 'false' ausgegeben...

    Wenn deine Aussage also richtig ist, entspricht mein Code nicht dem Standard, oder?



  • probier doch auch mal was der clang 3.8 dazu sagt: gcc.godbolt.org


  • Mod

    <a href= schrieb:

    [class.virtual]/8">If the class type in the covariant return type of D::f differs from that of B::f , **the class type in the return type of D::f shall be complete at the point of declaration of D::f or shall be the class type D **.



  • Das sagt wohl ziemlich alles, danke. Mein Code war also von Anfang an nicht korrekt und es wahr mehr oder weniger einfach Glück/Pech mit VC++

    clang meckert übrigens auch.


Log in to reply