2015-06-11 2 views
9
template <typename T> 
void QVector<T>::append(const T &t) 
{ 
    const T copy(t); 
    const bool isTooSmall = uint(d->size + 1) > d->alloc; 
    if (!isDetached() || isTooSmall) { 
     QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow :  QArrayData::Default); 
     reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt); 
    } 
    if (QTypeInfo<T>::isComplex) 
     new (d->end()) T(copy); 
    else 
     *d->end() = copy; 
    ++d->size; 
} 

Was ist der Grund, const T copy(t) anstelle von t nach Wert in die Methode zu machen? Was ist der Unterschied zwischen diesem und:QVector :: append() welcher Grund für das explizite Kopieren?

template <typename T> 
void QVector<T>::append(const T t) 
{ 
    const bool isTooSmall = uint(d->size + 1) > d->alloc; 
    if (!isDetached() || isTooSmall) { 
     QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow :  QArrayData::Default); 
     reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt); 
    } 
    if (QTypeInfo<T>::isComplex) 
     new (d->end()) T(t); 
    else 
     *d->end() = t; 
    ++d->size; 
} 
+0

Warum denkst du, dass es wichtig ist? Was motiviert Sie, ein Wertargument in Betracht zu ziehen? –

+2

Wahrscheinlichkeiten sind, halten sie einfach die Erklärung, um mit etwas im Einklang zu bleiben. Entweder Geschichte oder andere Funktionen. – nwp

Antwort

2

QVector Elemente erfordert assignable data types, zu sein, das heißt, sie

muss einen Standardkonstruktor zur Verfügung stellen, einen Kopierkonstruktor und einen Auftrag Operator.

Ihre Version von append erzwingen alle, während die Version erzwingen nicht Kopie Bau wenn QTypeInfo<T>::isComplex weg falsch und optimiert ist.

Hinweis: QTypeInfo<T>::isComplex wird zur Kompilierzeit aufgelöst.

Ich vermute, es ist eine ältere Anforderung, als QVector already existed in Qt2, die von 1999 weit vor C++ Standardisierung stammen.

2

Ich kann mir 2 mögliche Gründe vorstellen.

  1. Es folgt dem Stil der Rest des stl, kopieren und tauschen und übergeben von const &. Keine von diesen macht in dieser Situation eine gute Leistung oder eine korrekte Richtigkeit; aber es hält den Stil konsistent.

  2. Da der Parameter an eine Referenz gebunden ist, verhindert er die Eliminierung der Kopie beim Funktionsaufruf. Und weil die Elemente in einem Vektor zuordenbar sein müssen (dh nicht const), vermeidet es Kopie elision auf die Zuordnung in den Vektor

Dies macht den Code VIEL mehr tragbar und konsistent über Compiler. Das ist wahrscheinlich eine große Sache für die STL.

Copy Elision Wikipedia Entry

31) Wenn bestimmte Kriterien erfüllt sind, wird eine Implementierung erlaubt das Kopieren/Verschieben Bau eines Klassenobjekts zu verzichten, auch wenn das Kopieren/Verschieben Konstruktor und/oder Destruktor für das Objekt hat Nebenwirkungen. In solchen Fällen behandelt die Implementierung die Quelle und das Ziel der ausgelassenen Kopier-/Verschiebungsoperation als einfach zwei verschiedene Arten, auf dasselbe Objekt zu verweisen, und die Zerstörung dieses Objekts erfolgt zu dem späteren Zeitpunkt, zu dem die beiden Objekte gewesen wären ohne Eliminierung der Optimierung.123 Diese Eliminierung von Kopier-/Verschiebungsvorgängen, genannt copy elision, ist unter folgenden Umständen zulässig (die zur Eliminierung mehrerer Kopien kombiniert werden können):

- wenn ein temporäres Klassenobjekt nicht gebunden wurde zu einer Referenz (12.2) würde kopiert/verschoben auf ein Klassenobjekt mit dem gleichen cv-unqualifizierten Typ, das Kopieren/Verschieben Vorgang kann durch Konstruieren des temporäre Objekts direkt in das Ziel der weggelassen Kopie entfallen/bewegen

Verwandte Themen