2012-12-28 12 views
6

Powiel możliwe:
Does moving a vector invalidate iterators?Czy std :: vector :: data() jest zachowywany w ruchu?

Rozważmy następujące kody:

std::vector<T> prepare(T*& data) { 
    std::vector<T> buffer; 
    // Fill in buffer. 
    data = buffer.data(); 
    return buffer; 
} 

... 

T* data; 
auto vec = prepare(data); 
// line 12 

Czy to możliwe, że vec.data() != data w linii 12? Podobnie,

Czy to możliwe, że vec.data() != data w linii 5?

Praktycznie oba nie są możliwe w implementacji libstdC++ i libC++, ponieważ konstruktory ruchu są zaimplementowane jako proste przypisania do wskaźników, ale wygląda na to, że standard nie określa niczego na nim (podobnie jak w przypadku Is the capacity required to be preserved when moving a std::vector?). Czy "stała złożoność" gwarantuje, że vec.data() == data?

+0

Rzeczy, które unieważniają iteratory/wskaźniki są dość dobrze wyliczone. –

+0

Także pokrewne: http://stackoverflow.com/questions/4124989/does-stdvectorswap-invalidate-iterators –

Odpowiedz

0

Stała złożoność oznacza, że ​​kontener nie może kopiować/przenosić poszczególnych elementów, więc musi przenieść własność istniejącego magazynu na nowy obiekt, więc wskaźnik zwrócony przez data() musi być taki sam.

Przypisanie ruchu (zamiast konstrukcji ruchomej) jest prawdziwe tylko wtedy, gdy propagate_on_container_move_assignment jest prawdziwe w przypadku typu podzielnika wektora lub podzielniki są równe.

+0

Pewna szalona implementacja może przenieść/skopiować stałą liczbę pojedynczych elementów. – zch

+0

@zch: Jest to zabronione wymogiem sąsiadujących. –

+0

@BenVoigt, a co z 'if (<10) copyAll(); else moveOwnership(); '? – zch