Qualcuno può spiegare perché l'operatore [] non è implementato per una lista std ::? Ho cercato un po 'ma non ho trovato una risposta. Non sarebbe troppo difficile da implementare o mi manca qualcosa?Perché non c'è un operatore [] per una lista std ::?
risposta
Il recupero di un elemento per indice è un'operazione O (n) per l'elenco collegato, che è ciò che è std::list
. Così è stato deciso che fornire operator[]
sarebbe ingannevole, dal momento che le persone sarebbero tentati di utilizzare attivamente, e poi si vedrebbe il codice come:
std::list<int> xs;
for (int i = 0; i < xs.size(); ++i) {
int x = xs[i];
...
}
che è O (n^2) - molto brutto. Pertanto, lo standard ISO C++ indica specificamente che tutte le sequenze STL che supportano operator[]
dovrebbero farlo in tempo costante ammortizzato (23.1.1 [lib.sequence.reqmts]/12), che è ottenibile per vector
e deque
, ma non list
.
Per i casi in cui è effettivamente necessario questo genere di cose, è possibile utilizzare std::advance
algoritmo:
int iter = xs.begin();
std::advance(iter, i);
int x = *iter;
Non sarebbe troppo difficile (per l'implementatore) ma sarebbe troppo difficile in fase di esecuzione, poiché la prestazione sarà terribile nella maggior parte dei casi. Costringere l'utente a passare attraverso ogni link renderà più ovvio ciò che sta accadendo in là rispetto a "myList [102452]".
Per elaborare un operatore bit [] è un'operazione a tempo costante in tutti gli altri punti in cui viene utilizzata. Dare lo stesso nome a un'operazione O (n) sarebbe incoerente e confuso. – dmckee
Beh, è O (log n) in una mappa ma ho capito. –
In una mappa non è decisamente un indice posizionale, il che è abbastanza ovvio - tranne forse quando la chiave della mappa è un numero intero, ma se confondi l'accesso posizionale con la ricerca della chiave, hai già problemi molto più grandi;) –
Credo di aver trovato la risposta in un altro SO inviare Extending std::list
"l'operatore [] è O (N) time "- questo è esattamente il motivo per cui non è incluso in standard std :: list <>. - Michael Burr 14 dicembre alle 17:29
Tuttavia, è questa l'unica ragione?
EDIT: Sembra che, come si è detto, è più una questione di coerenza in termini di prestazioni, quindi di prestazioni rigorose.
Vuoi dire che non è una ragione sufficiente? :-) –
Lo è. Guardando altrove, .NET 'LinkedList' non fornisce un indicizzatore per gli stessi motivi in gran parte - è semplicemente troppo ingannevole. Tradizionalmente, quando qualcosa ha un indicizzatore posizionale, si presume che l'operazione sia O (1). –
In realtà, non c'è assolutamente alcuna ragione per non fornire all'operatore [] o almeno il metodo a (int), a causa dei due motivi:
- E 'doppia lista collegata, quindi è necessario muoversi a la maggior parte delle dimensioni()/2 posiziona il tuo iteratore per ottenere il tuo indice, e i costi per mantenere internamente pochi altri iteratori fissi sono molto bassi. E alla fine, la libreria Qt fornisce l'operatore [] e l'at, e non vedo costi di performance che lo utilizzano.
- forzare le persone a non usare è un'abitudine di programmazione molto brutta, perché un elenco è molto contenitore utilizzabile, se si ha un "accesso casuale" vicino all'accesso collegato, vi sono vari esempi quando è necessario l'accesso, a seconda di quale punto di esecuzione.
Questo è puramente basato sulla tua opinione o hai creato un bel scenario di test, in cui mostri che la tua implementazione personalizzata di 'std :: list
- 1. Perché non esiste un operatore << per std :: unique_ptr?
- 2. Perché non esiste un operatore [] per std :: shared_ptr?
- 3. Perché `std :: initializer_list` non fornisce un operatore di pedici?
- 4. Cancellare uno std :: vector richiede un operatore di assegnazione. Perché?
- 5. Perché una funzione di conversione non funziona con std :: string?
- 6. Operatore! = È ambiguo per std :: reverse_iterator C++
- 7. Perché non usa il mio operatore sovraccarico per ++?
- 8. Perché scrivere una stringa: std :: cout causando un operatore sconosciuto << errore?
- 9. operatore condizionale nella lista dei membri-inizializzazione
- 10. restituendo std :: string/std :: lista da dll
- 11. operatore python, nessun operatore per "non in"
- 12. Perché non esiste un costruttore di riserva per std :: string?
- 13. di errore: "non può competere con operatore +", per la lista iteratore
- 14. Perché std :: hash non è stato definito per std :: weak_ptr in C++ 0x?
- 15. Perché non c'è std :: stou?
- 16. Perché lista [:: - 1] non uguale lista [: len (lista): - 1]?
- 17. Perché questo operatore = chiamata ambigua?
- 18. Perché sapply() restituisce una lista?
- 19. Perché le doppie parentesi graffe vuote {{}} creano una lista std :: initializer_list <double> con un elemento, non zero?
- 20. Clang, std :: shared_ptr e std :: meno/operatore <
- 21. come posso usare std :: enable_if in un operatore di conversione?
- 22. C++ std :: set Trova funzione overloading == operatore
- 23. operatore non valido <durante l'ordinamento std :: list
- 24. vb.net - Perché operatore + = non consentito per ULONG (UInt64)?
- 25. Perché Kotlin non supporta "operatore ternario"
- 26. Perché std :: sort crash se la funzione di confronto non è come operatore <?
- 27. Perché la sizeof è considerata un operatore?
- 28. std :: copia a std :: cout per std :: coppia
- 29. Java non può sovraccaricare alcun operatore. Perché?
- 30. Perché non è std :: string :: max_size() == std :: string :: allocator :: max_size()
Quindi, in pratica, si tratta solo di impedire alle persone di commettere errori? –
sì.O di non fare promesse che non puoi mantenere. Nell'STL, l'operatore [] promette * l'accesso * efficiente * a elementi arbitrari. – jalf
E grazie Pavel per il riferimento standard C++! –