2016-04-15 2 views
0

Dieser Code wird kompiliert (Visual Studio 2013). Beachten Sie, dass ich Set, nicht Set<T> als Parameter an operator = im Funktionskörper übergebe, der außerhalb der Klassendefinition liegt. Aber ich kann Set nicht zurückgeben oder es muss ein Mitglied von Set sein; es muss Set<T> zurückgeben und ein Mitglied von Set<T> sein.In Template-Klassenmember Funktionskörper außerhalb der Klassendefinition, wann sind Template-Parameter erforderlich?

Wo ist es legitim, die Template-Parameter wegzulassen? Inside the class definition, und wo sonst?

Ist dies eine Änderung des Standards? Ich versuche, die Kompatibilität mit allen vorhandenen Versionen, einschließlich 98 zu erhalten.

template <typename T> 
class Set 
{ 
public: 
    Set() {}   

    const Set& operator=(const Set& rhs); 
    //Shouldn't this have to be 
    //const Set<T>& operator= (const Set<T>& rhs); ? 

}; 

template <typename T> 
const Set<T>& Set<T>::operator= (const Set& rhs) //<-- HERE 
{ 
    Set temp;         //<-- AND HERE 
    /* ... */ 
    return *this; 
} 

int main() 
{ 
    Set<int> S, T; 
    T = S; 
} 
+0

AFAIK nur Klassen tun dies, da sie eine injizierte-class-name – NathanOliver

+0

haben und hier: 'template Auto Set :: operator = (const Set &) -> const Set & ' –

+0

' void main' ist ungültig und hätte viele (die meisten) Leser daran gehindert, Ihren Code auszuprobieren. Das habe ich behoben. Bitte geben Sie keinen Code mit 'void main' ein, es sei denn, die Frage bezieht sich speziell darauf, weil es neue Leser irreführt und es unmöglich macht, Ihren Code einfach zu kopieren und einzufügen, es sei denn, Sie verwenden einen der wenigen Compiler das akzeptiere es. –

Antwort

0

Der Klassenname wird im Klassenbereich verfügbar gemacht. In einer separaten Memberdefinition befinden Sie sich nach der Übergabe der C++ 03-Rückgabetypspezifikation und des Funktionsnamens im Klassenbereich. Somit ist dies OK in C++ 03:

template< class T > 
Set<T> const& Set<T>::operator=(Set const& rhs) 

Und das ist OK in C++ 11:

template< class T > 
auto Set<T>::operator=(Set const& rhs) -> Set const& 

Das hat nicht wirklich etwas mit Vorlagen zu tun hat, aber es hat mit dem Zugriff auf einen Namen zu tun, der im Klassenumfang verfügbar ist.

Zum Beispiel in C++ 03 würden Sie

struct S 
{ 
    struct Inner {}; 
    Inner foo(); 
}; 

S::Inner S::foo() { return Inner(); } 

zu schreiben, während sie mit C++ 11 und später können Sie

struct S 
{ 
    struct Inner {}; 
    auto foo() -> Inner; 
}; 

auto S::foo() -> Inner { return {}; } 

schreiben, das ein guter Grund ist unter viele andere, um die Syntax des abschließenden Rückgabetyps als eine einzige Syntaxkonvention zu übernehmen.


This ist nicht OK entweder in C oder C++, unabhängig von Standard, Jahr:

void main() //! NOT VALID. 
+0

Wissen Sie, ob das, was Sie hier haben, auch in C++ 98 gültig ist? –

+0

Der C++ 03-Code ist mit C++ 98-Compiler gültig. Das einzige neue Feature, das in C++ 03 eingeführt wurde, war die Wert Initialisierung. C++ 03 war nur ein * technisches Corrigendum * von C++ 98, damals TC1 genannt (es war das erste und einzige). –

Verwandte Themen