Czy ktoś może wyjaśnić, dlaczego nie jest operator [] wdrożony dla std :: list? Szukałem trochę, ale nie znalazłem odpowiedzi. Nie byłoby to zbyt trudne do wdrożenia lub czegoś brakuje?Dlaczego nie ma operatora [] dla std :: list?
Odpowiedz
Odzyskiwanie element wskaźnikiem jest O (n) działanie na listę, na której znajduje się co std::list
IS. Więc zdecydowano, że zapewnienie operator[]
byłoby zwodnicze, ponieważ ludzie będą kuszeni, aby aktywnie wykorzystywać ją, a potem by zobaczyć kod jak:
std::list<int> xs;
for (int i = 0; i < xs.size(); ++i) {
int x = xs[i];
...
}
który wynosi O (n^2) - bardzo nieprzyjemny. Tak więc standard ISO C++ wspomina, że wszystkie sekwencje STL, które obsługują operator[]
, powinny robić to w zamortyzowanym stałym czasie (23.1.1 [lib.sequence.reqmts]/12), co jest możliwe dla vector
i deque
, ale nie list
.
W przypadkach, w których rzeczywiście potrzebują tego rodzaju rzeczy, można użyć std::advance
algorytmu:
int iter = xs.begin();
std::advance(iter, i);
int x = *iter;
To nie byłoby zbyt trudne (dla realizatora), ale byłoby to zbyt trudne w czasie wykonywania, ponieważ wydajność będzie straszny w większości przypadków. Zmuszenie użytkownika do przejścia przez każdy link sprawi, że będzie bardziej oczywiste, co się tam dzieje, niż "myList [102452]".
opracowanie operator bitowy [] jest stałe w czasie operacji we wszystkich innych miejscach nie jest używany. Nadanie tej samej nazwy operacji O (n) byłoby niespójne i mylące. – dmckee
To jest O (log n) na mapie, ale rozumiem. –
Na mapie to nie jest zdecydowanie pozycyjny wskaźnik, który jest dość oczywista - może z wyjątkiem gdy klucz mapa jest liczbą całkowitą, ale jeśli jesteś mylące pozycyjną dostęp z klucz wyszukiwania, masz już dużo większe problemy;) –
Myślę, że znalazłem odpowiedź w innym SO zakładać Extending std::list
„swojego operatora [] to czas O (N) "- to właśnie dlatego jest niewpisane w standardzie std :: list <>. - Michael Burr 14 grudnia o 17:29
Ale czy to jedyny powód?
EDIT: Wydaje się jednak, jak ludzie wspomniano jest to bardziej kwestia spójności w zakresie wydajności następnie ściśle wydajności.
Masz na myśli, że to nie wystarczający powód? :-) –
To jest. Patrząc gdzie indziej, .NET 'LinkedList' nie dostarcza indeksu z tych samych powodów - jest po prostu zbyt zwodniczy. Tradycyjnie, gdy coś ma indeksujący położenie, przyjmuje się, że operacja to O (1). –
Faktycznie, nie ma absolutnie żadnego powodu, aby nie dostarczyć operator [] lub przynajmniej sposób na (int), ponieważ z dwóch powodów:
- Jest podwójna lista powiązane, więc trzeba się poruszać z prędkością większość size()/2 umieszcza twój iterator w celu uzyskania indeksu, a koszty wewnętrznego utrzymywania kilku kolejnych stałych iteratorów są bardzo niskie. I na koniec biblioteka Qt dostarcza operatorowi [] i at, i nie widzę kosztów wydajności z niego korzystających.
- zmuszanie ludzi coś nie do wykorzystania jest bardzo złe programowanie nawyk, bo lista będzie znacznie użyteczny pojemnik, jeśli masz „swobodnego dostępu” w pobliżu połączonego dostępu, istnieje przykłady odmiany, gdy trzeba mieć dostęp, w zależności na który punkt kontrolny.
Czy to jest czysto bazowe według twojej opinii, czy stworzyłeś niezły scenariusz testowy, w którym pokazujesz, że twoja niestandardowa implementacja 'std :: list
- 1. Dlaczego nie ma std :: stou?
- 2. Dlaczego nie ma std :: protect?
- 3. Dlaczego nie ma std :: inplace_merge_unique?
- 4. C++ Lambda nie ma operatora()
- 5. Dlaczego nie ma algorytmu std :: copy_if?
- 6. Alternatywa dla „w” operatora dla zagnieżdżonych list
- 7. Jak obejść fakt, że funkcja std :: nie ma operatora ==?
- 8. Dlaczego nie ma konstruktora rezerwującego dla std :: string?
- 9. ma int mieć operatora ==
- 10. Dlaczego std :: move na std :: unique_lock nie ma żadnego efektu?
- 11. Dlaczego nie używa się mojego przeciążonego operatora dla ++?
- 12. Dlaczego nie mogę użyć operatora <on 'std :: deque'?
- 13. Dlaczego nie std :: sort używać mojego operatora <realizacji
- 14. Dlaczego nie jest ustawieniem operatora [] dla map STL?
- 15. Dlaczego C++ std :: list :: clear() nie wywołuje destruktorów?
- 16. Dlaczego nie mogę zapisać funkcji boost :: w std :: list?
- 17. Dlaczego funkcja @JsonUnwrapped nie działa dla list?
- 18. Mysema Querydsl: Nie ma metody JPAQuery # list()
- 19. sortowania std :: list przy użyciu std :: sort
- 20. Dlaczego nie można znaleźć przeciążonego operatora == dla std :: weak_ptr utworzonego przez typ zdefiniowany w przestrzeni nazw?
- 21. Czy nie ma specjalizacji od std :: hash dla standardowych kontenerów?
- 22. Względna wydajność std :: vector vs. std :: list vs. std :: slist?
- 23. Usuwanie std :: vector wymaga operatora przypisania. Czemu?
- 24. Czy powinienem używać operatora + = zamiast operatora + do łączenia std :: string?
- 25. Dlaczego nie ma typeklasy dla typów kontenerów?
- 26. Dlaczego nie ma metody getContentView() dla działania?
- 27. Dlaczego nie ma wbudowanego typu dla DateTime?
- 28. Dlaczego nie ma Xcode dla Windows?
- 29. Dlaczego nie ma wystąpienia wystąpienia dla funkcji?
- 30. niepoprawny operator <podczas sortowania std :: list
Więc, w zasadzie, chodzi tylko o zapobieganie popełnianiu błędów przez ludzi? –
tak.Albo nie składanie obietnic, których nie możesz dotrzymać. W STL operator [] obiecuje * wydajny * dostęp do dowolnych elementów. – jalf
I dziękuje Pavel za standardowe odniesienie C++! –