Definition einer Memberfunktion einer Template-Klasse



  • Hallo an alle,

    ich versuche in einer Klasse (mit Templates) eine Funktion mit generischem Rückgabewert zu erzeugen.
    Ich habe mein Problem, soweit vereinfacht, dass unterer Code ungefähr zeigt, was getan werden soll und trotzdem noch einen Kompilierungsfehler schmeißt.
    Das using C = T; ist natürlich vereinfacht (weil sonst sinnlos), eigentlich steht da irgendetwas mit std::conditional ....

    template< class T >
    class A
    {
    public:
    	A() = default;
    
    	using C = T;
    
    	C Test();
    
    	C c = C();
    };
    
    int main()
    {
    	A<int> a;
    }
    
    template<class T>
    A<T>::C A<T>::Test()
    {
    	return c;
    }
    

    Obiger Code erzeugt mit VS 2015 folgende Meldung:

    1> warning C4346: "C": Abhängiger Name ist kein Typ
    1> note: Präfix mit "typename" zum Angeben eines Typs
    1> error C2061: Syntaxfehler: Bezeichner "C"
    

    MfG
    Hlymur



  • Eigentlich sagt die Fehlermeldung ja schon alles. Zeile 20 fehlt ein typename:

    template<class T>
    typename A<T>::C A<T>::Test()
    {
        return c;
    }
    

  • Mod

    Wenn du den Rückgabetyp vor die declarator-id schreibst, muss dort noch ein typename hin.
    Schreib' entweder

    template<class T> 
    typename A<T>::C A<T>::Test() 
    { 
        return c; 
    }
    

    Oder

    template<class T> 
    auto A<T>::Test() -> A::C
    { 
        return c; 
    }
    


  • @Arcoth
    Letzteres gefällt VS2015 irgendwie nicht. Man braucht immer noch ein typename.



  • Arcoth schrieb:

    Wenn du den Rückgabetyp vor die declarator-id schreibst, muss dort noch ein typename hin.
    Schreib' entweder

    template<class T> 
    typename A<T>::C A<T>::Test() 
    { 
        return c; 
    }
    

    Perfekt,danke für schnelle antwort


  • Mod

    sebi707 schrieb:

    @Arcoth
    Letzteres gefällt VS2015 irgendwie nicht. Man braucht immer noch ein typename.

    Wird allerdings sehr explizit vom Standard erlaubt:

    §14.6/7 schrieb:

    Within the definition of a class template or within the definition of a member of a class template following the declarator-id, the keyword typename is not required when referring to the name of a previously declared member of the class template that declares a type.

    Das selbe Ergebnis kann auch anderweitig hergeleitet werden.

    §3.4.3/3 schrieb:

    In a declaration in which the declarator-id is a qualified-id, names used before the qualified-id being declared are looked up in the defining namespace scope; names following the qualified-id are looked up in the scope of the member’s class or namespace.

    §14.6.2.1/(1.1) schrieb:

    A name refers to the current instantiation if it is
    — in the definition of a […] a member of a class template[…], the injected-class-name (Clause 9) of the class template or nested class,

    §14.6.2.1/(5.2) schrieb:

    A name is a member of the current instantiation if it is
    — A qualified-id in which the nested-name-specifier refers to the current instantiation and that, when looked up, refers to at least one member of a class that is the current instantiation or a non-dependent base class thereof.

    Da A::C demnach einen Member der aktuellen Instantiierung darstellt, braucht es nicht mit typename qualifiziert zu werden.



  • Hlymur schrieb:

    1> warning C4346: "C": Abhängiger Name ist kein Typ
    1> note: Präfix mit "typename" zum Angeben eines Typs
    1> error C2061: Syntaxfehler: Bezeichner "C"
    

    Fehlermeldungen auf deutsch???

    Und es gibt weder Template-Klassen noch Template-(Member-)Funktionen.


Anmelden zum Antworten