2013-10-03 14 views
14

Ich lese, dass die Vorlage copy-con ist nie Standard-Kopie-Konstruktor, und Vorlage Zuweisung-op ist nie ein Kopie Zuweisungsoperator.Kopieren Konstruktor der Vorlage Klasse

Ich konnte nicht verstehen, warum diese Einschränkung notwendig ist, und gerade ging online ideone und zurück ein test program aber hier Copy-Konstruktor nie weiter aufgerufen wird auf googeln ich über templatized Konstruktor kam und versuchte, das aber noch nie Anrufe Copy-Konstruktor .

#include <iostream> 
using namespace std; 

template <typename T> class tt 
{ 
    public : 
    tt() 
    { 
     std::cout << std::endl << " CONSTRUCTOR" << std::endl; 
    } 
    template <typename U> const tt<T>& operator=(const tt<U>& that){std::cout << std::endl << " OPERATOR" << std::endl;} 
    template <typename U> tt(const tt<U>& that) 
    { 
     std::cout << std::endl << " COPY CONSTRUCTOR" << std::endl; 
    } 
}; 


tt<int> test(void) 
{ 
    std::cout << std::endl << "  INSIDE " << std::endl; tt<int> a; return a; 
} 

int main() { 
    // your code goes here 
    tt<int> a ; a = test(); 

    return 0; 
} 

Kann jemand erklärt mir den ganzen Grund für diese Einschränkung setzen und auch, wie eine Kopie Konstruktor der Template-Klasse zu schreiben.

Dank

+2

[Copy-elision.] (Http://stackoverflow.com/questions/12953127/what-are-copy-elision-and-return-value-optimization) – 0x499602D2

+1

Es gibt keinen "Standard-Kopierkonstruktor". Es gibt nur * einen * Kopierkonstruktor. Eine Vorlage ist es nie. –

+0

Ich bearbeitet Code und lief es in ideone, aber immer noch kopieren Konstruktor nicht aufgerufen werden. aber ich verstehe auch nicht Grund hinter dieser Einschränkung – anonymous

Antwort

18

Es gibt strenge Regeln, was einen Kopierkonstruktor bildet (vgl C 11 ++, 12.8):

  • Es ist nicht eine Vorlage.

  • Für eine Klasse T muss das erste Argument Typ haben T & oder T const & oder T volatile & oder T const volatile &.

  • Wenn es mehr als ein Argument hat, müssen die weiteren Argumente Standardwerte haben.

Wenn Sie keine Kopie Konstruktor deklarieren, wird eine Kopie Konstruktor des Formulars T::T(T const &)deklariert ist implizit für Sie. (Es kann oder kann nicht tatsächlich definiert werden, und wenn es definiert ist, kann es als gelöscht definiert werden.)

(Die üblichen Überladungsauflösungsregeln bedeuten, dass Sie maximal vier Kopierkonstruktoren haben können, einen für jede CV-Qualifikation .)

Es gibt analoge Regeln für Bewegungskonstruktoren, mit && anstelle von &.

17

ich nicht kommentieren kann, warum dies ist, wie es ist, aber hier ist, wie Sie einen Kopierkonstruktor und Zuweisungsoperator für eine Klassenvorlage schreiben:

template <class T> 
    class A 
    { 
     public: 
     A(const A &){} 
     A & operator=(const A& a){return *this;} 
    }; 

und das ist es.
Der Trick hier ist, dass, obwohl A eine Vorlage ist, wenn Sie darauf innerhalb der Klasse als A verweisen (wie in den Funktionssignaturen) wird es als der vollständige Typ A<T> behandelt.

+1

Ich fand, dass die Verwendung von A (const A &) {} gibt keinen Fehler ... – Daniel

+4

@Daniel Das ist, weil 'A ' bezieht sich auch auf den vollständigen Typ der Klasse, 'A' ist nur eine Kurzschrift, die Sie innerhalb der Klasse verwenden können. – SirGuy

+0

@NicolaiNita Ist das nicht, was der erste Kommentar hier sagt? – SirGuy

Verwandte Themen