2015-06-11 20 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; 
} 

Jaki jest powód, aby const T copy(t) zamiast podania t przez wartość do metody? Jaka jest różnica między tym a:QVector :: append() jaki jest powód jawnego kopiowania?

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

Jak myślisz, dlaczego to ma znaczenie? Jaka jest Twoja motywacja do rozważenia argumentu wartości? –

+2

Są szanse, że po prostu zachowują deklarację, aby pozostać w zgodzie z czymś. Historia lub inne funkcje. – nwp

Odpowiedz

2

QVector wymaga elementów będzie assignable data types, co oznacza, że ​​

musi zapewnić konstruktor domyślny, konstruktor kopiujący i operator przypisania .

Ich wersja append egzekwować wszystko, podczas gdy wersja nie będzie egzekwować kopiowania budowę jeśli QTypeInfo<T>::isComplex jest fałszywy i zoptymalizowane z dala.

Uwaga: QTypeInfo<T>::isComplex zostaje rozstrzygnięty w czasie kompilacji.

Podejrzewam, że jest to dotychczasowe wymaganie, ponieważ QVector already existed in Qt2, które pochodzi z 1999 na długo przed standaryzacją C++.

2

Mogę wymyślić 2 możliwe przyczyny.

  1. Wynika styl reszty STL, kopiowania i wymiany i przechodzą przez const &. Żadne z nich nie wykonuje w tej sytuacji żadnych dobrych wyników ani poprawności poprawności; ale zachowuje spójność stylu.

  2. Ponieważ parametr jest powiązany z odwołaniem, pozwala uniknąć kopiowania w wywołaniu funkcji. A ponieważ elementy w wektorze muszą być przypisane (nie const), unika kopiowania elizja na przypisanie do wektora

To sprawia, że ​​kod DUŻO bardziej przenośne i spójne kompilatorów. Co jest prawdopodobnie wielką sprawą dla stl.

Copy Elision Wikipedia Entry

31) Gdy pewne kryteria są spełnione, to implementacja wolno pominąć budowę kopia/ruch obiektu klasy, nawet jeśli kopia/konstruktor ruch i/lub destruktor dla obiektu mają skutki uboczne. W takich przypadkach implementacja traktuje źródło i cel pominiętej operacji kopiowania/przenoszenia jako dwa różne sposoby odnoszenia się do tego samego obiektu, a zniszczenie tego obiektu następuje w późniejszym czasie, gdy te dwa obiekty zostałyby usunięte. zniszczona bez optymalizacji.123 Ta elizacja operacji kopiowania/przenoszenia, zwana copy elision, jest dozwolona w następujących okolicznościach (które mogą być łączone w celu wyeliminowania wielu kopii):

- gdy tymczasowy obiekt klasy, który nie został związany do odnośnika (12.2) zostaną skopiowane/przeniesione do obiektu klasy z tego samego typu cv-niewykwalifikowanego, operacja kopiowania/ruch może być pominięte przez tworzącego tymczasowy obiekt bezpośrednio do docelowej pominiętym kopii/przenieść

Powiązane problemy