2011-12-07 19 views
11

Biorąc pod uwagę std::vector<std::unique_ptr<SomeType> >, czy jest legalne używanie na nim remove_if? Innymi słowy, biorąc pod uwagę ten kod:Czy możesz użyć `std :: remove_if` na kontenerze` std :: unique_ptr`?

std::vector<std::unique_ptr<SomeType> > v; 
// fill v, all entries point to a valid instance of SomeType... 
v.erase(std::remove_if(v.begin(), v.end(), someCondition), v.end()); 

, mam zagwarantowane po erase, że wszystkie wskaźniki są nadal w v ważny. Wiem, że biorąc pod uwagę intuicyjną implementację std::remove_if, i biorąc pod uwagę wszystkie implementacje, na które patrzyłem, będą one. Chciałbym wiedzieć, czy jest coś w standardzie , które to gwarantuje; to jest, że std::remove_if nie może kopiować żadnego z prawidłowych wpisów bez kopiowania kopii do ostatecznej lokalizacji .

(Jestem, oczywiście, przy założeniu, że stan nie kopiuje Jeśli warunek ma sygnaturę podobnego.

struct Condition 
{ 
    bool operator()(std::unique_ptr<SomeType> ptr) const; 
}; 

, to oczywiście, wszystkie wskaźniki będą nieważne po remove_if.)

+7

James Kanze zadaje pytania - bardzo rzadkie zjawisko! – Nawaz

+3

'unique_ptr' nie jest konstrukcją kopiowalną, więc jeśli użyjesz tego predykatu, twój kod się nie skompiluje. – interjay

+1

Dlaczego nie? 'std :: unique' nie jest kopiowalny, ale ruchomy. Można go przenieść na koniec pojemnika. –

Odpowiedz

2

25.3.8 w N3290 mówi o usunięcie funkcji:

wymaga: * Typ pierwszy spełniają wymogów MoveAssignable (tabela 22).

i

Uwaga: każdy element przedziału [RET ostatni), gdzie retencji jest zwrócona wartość posiada ważne lecz unspeci stanu fi DE, ponieważ algorytmy wyeliminowanie elementów poprzez zamianę z lub przesuwając się z elementów, które pierwotnie znajdowały się w tym zakresie.

Oznacza to, że zależy to od operatora predykatu. Ponieważ twój predykat nie tworzy kopii, elementy nie będą kopiowane.

+0

§25.3.8/1 jest ograniczeniem dla typu docelowego, a nie implementacją 'remove' w wersji . Szukałem tego w §25.3.8/6. Too złe, to jest notatka, a nie normatywna. Ale czyni to jasno. Powinienem przeczytać notatki, a nie tylko tekst normatywny, przed opublikowaniem . +1 i tak uważam to za ostateczną odpowiedź, jeśli nikt nie znajdzie niczego bardziej konkretnego. –

+0

Mam n3242. Czy po tym dodano § 25.3.8/6? Mój/6 omawia temat 'remove_copy [_if]'. – kennytm

+2

Uważam, że notatka jest niepoprawna. Dobrze, że nie jest normatywna. ;-) Algorytm nie może zamieniać elementów, ponieważ elementy nie muszą być wymienialne. Algorytm może używać tylko przypisania ruchu. –

5

Podobnie jak erase() i resize(), remove_if() będzie przenieść elementy (ewentualnie przez swapping), a więc elementy kontenerów nie muszą być copyable. Nie ma nic szczególnego w unique_ptr, to tylko kolejny typ tylko ruchu.

Jak wskazujesz, predykat powinien oczywiście przyjmować elementy przez const-reference. Ponownie, podobnie jak w przypadku każdego ruchomego typu.

+0

Gdzie jest to określone w standardzie? I co ważniejsze, gdzie to jest stwierdził, że 'remove_if' nie przesuwa się do jakiegoś tymczasowego, może później do zostawić tam wartość, ponieważ określa, że ​​nie trzeba go umieszczać w innym miejscu? Kontenery i funkcje funkcji zostały zmienione na , aby odzwierciedlić semantykę ruchu, ale nie jestem świadomy żadnych zmian w języku opisującym "remove_if" w tym zakresie. –

+1

@JamesKanze: §25.3.8/1? – kennytm

+0

@KennyTM: Pokonaj mnie, dzięki! –

Powiązane problemy