2014-11-15 16 views
6

Ustalono, że std::unordered_set i std::unordered_map ma zakres erase(first, last), co moim zdaniem jest kolejnym dobrym sposobem na strzelanie sobie w nogi.Jaki jest prawdziwy przypadek użycia w przypadku wymazywania według std :: unordered_ (set | map)?

Może ktoś zna rzeczywiste przypadki użycia tej funkcji?

Czy może to być uznane za zły projekt?

+2

Wymazywanie na podstawie zakresu jest częścią ogólnych wymagań nieuporządkowanego kontenera i jest łatwe do dostarczenia i wdrożenia. Przypuszczam, że trudniej byłoby jawnie * usunąć * to przeciążenie z map unikatowego klucza, niż po prostu go zostawić, nawet jeśli nie jest to zbyt użyteczne. Zauważysz, że tak naprawdę nie jest wspomniany w sekcjach dotyczących nieuporządkowanej mapy i zestawu. –

+0

Jestem skłonny zaakceptować ten komentarz jako poprawną odpowiedź, ale nie mogę – acc15

Odpowiedz

1

OK, I have an answer. W C++ 14 wyjaśniono, że elementy, które nie są wymazywane, zachowują tę samą kolejność "dzięki temu można wymazać poszczególne elementy podczas iteracji przez kontener."

Twoja iteracja będzie w przypadkowej kolejności. Możesz jednak usunąć wszystkie odwiedzone podczas jednego połączenia. Zakres do usunięcia będzie taki sam, jak zakres iteracji.

+0

innymi słowy podczas iteracji nad sekwencją "losowo uporządkowaną" muszę śledzić zakres tylko po to, aby wykonać kasowanie w jednej operacji? to prawdopodobnie może przyspieszyć duże sekwencje ... ale to bardzo zależy od dystrybucji danych, które powinny zostać usunięte. – acc15

+1

Jeśli zamówienie nie ma znaczenia, nie ma również dystrybucji. Załóżmy, że zbierasz listę domów do malowania i przechowujesz ją w nieuporządkowanej mapie, gdy dane nadchodzą. Po uruchomieniu procesu malowania trwa * dowolne * 10 elementów (jeśli jest ich więcej) i wydaje zlecenia pracy dla załogi ** i ** usuwa je z listy. Masz 'begin' przez jak daleko posuniesz się do przodu iteratora, przetwarzając' * it' w pętli. Następnie usuń 'begin(), to 'usuń tylko te przetworzone. Jest to bardziej wydajne niż wymazywanie każdego z kolejnych iteratorów. –

+0

Tak, mam pomysł, dziękuję. Jednak nadal wygląda to jak bardzo specyficzne zadanie (dlaczego 10 domów, dlaczego nie wszystkie? - jeśli wszystko to "clear()" - byłoby lepsze) - ale to zadanie może się zdarzyć. Dzięki jeszcze raz. – acc15

2

Myślę, że to zapewnienie zgodności ze zwykłą mapą i zestawem.

Ale nadal uważam, że jest to z zasady użyteczne. Jeśli zakres wartości został wycofany, chcesz usunąć je z kolekcji. Ale normalny przypadek użycia jest lepszy (milion razy częstszy niż wstawianie/usuwanie) i nie jest wykonywany, więc nieuporządkowana wersja jest dobra.

Jak może Cię to zastrzelić? Nie różni się to od usuwania każdego z nich w pętli. Ah, zwykły start, przesunięcie do przodu w przód nie będzie działać, więc uważasz, że dostarczona funkcja nie robi tego, czego potrzeba, aby zrobić to dobrze, ale robi to samo trajektoria przemieszczania się w przód, która zadziałałaby na mapie, ale zepsuła się an unordered_map?

Ojej, prawda?

+1

Tak, przełączanie między std :: map i std :: unordered_map nie jest możliwe, gdy używasz kasowania na podstawie zakresu(), ponieważ w przypadku kolekcji nieuporządkowanej otrzymasz bardzo - trudne do przewidzenia wyniki – acc15