¿Alguien puede explicar por qué el operador [] no está implementado para una lista std ::? He buscado un poco pero no he encontrado una respuesta. No sería muy difícil de implementar o me estoy perdiendo algo?¿Por qué no hay un operador [] para una lista estándar?
Respuesta
Recuperar un elemento por índice es una operación O (n) para la lista vinculada, que es lo que std::list
es. Por lo tanto, se decidió que sería proporcionar operator[]
engañosa, ya que las personas se verían tentados a utilizar activamente, y luego se vería código como:
std::list<int> xs;
for (int i = 0; i < xs.size(); ++i) {
int x = xs[i];
...
}
que es O (n^2) - muy desagradable. Por lo tanto, el estándar ISO C++ menciona específicamente que todas las secuencias STL que admiten operator[]
deben hacerlo en tiempo constante amortizado (23.1.1 [lib.sequence.reqmts]/12), que se puede alcanzar para vector
y deque
, pero no list
.
Para los casos en que realmente necesita ese tipo de cosas, puede utilizar std::advance
algoritmo:
int iter = xs.begin();
std::advance(iter, i);
int x = *iter;
No sería demasiado difícil (para el implementador) pero sería demasiado difícil en tiempo de ejecución, ya que el rendimiento será terrible en la mayoría de los casos. Obligar al usuario a ir a través de cada enlace hará que sea más obvio lo que está sucediendo ahí que 'myList [102452]' lo haría.
Para elaborar un operador de bit [] es una operación de tiempo constante en todos los demás lugares donde se usa. Dar el mismo nombre a una operación O (n) sería inconsistente y confuso. – dmckee
Bueno, es O (log n) en un mapa, pero entiendo su punto. –
En un mapa, definitivamente no es un índice posicional, lo cual es bastante obvio, excepto quizás cuando la clave del mapa es un número entero, pero si confunde el acceso posicional con la búsqueda de claves, ya tiene problemas mucho mayores;) –
Creo que he encontrado la respuesta en otro SO publicar Extending std::list
"su operador [] es O (N) time "- este es exactamente el motivo por el cual no está incluido en estándar del estándar <>. - Michael Burr 14 de diciembre a las 17:29
Aún así, ¿es esa la única razón?
EDITAR: Parece que, como las personas lo mencionaron, es más una cuestión de consistencia con respecto al rendimiento que estrictamente al rendimiento.
¿Quiere decir que no es razón suficiente? :-) –
Lo es. Buscando en otra parte, .NET 'LinkedList' no proporciona un indexador por las mismas razones, es demasiado engañoso. Tradicionalmente, cuando algo tiene un indexador posicional, se supone que la operación es O (1). –
En realidad, no hay absolutamente ninguna razón para no proporcionar el operador [] o, al menos, método al (int), debido a las dos razones:
- Es lista doblemente enlazada, por lo que necesita para moverse en la mayoría del tamaño()/2 coloca su iterador para obtener su índice, y los costos para mantener internamente pocos iteradores fijos más son muy bajos. Y al final, la biblioteca de Qt proporciona el operador [] y el at, y no veo el costo de rendimiento al usarlo.
- obligar a las personas a no usar es un hábito de programación muy malo, porque una lista será un contenedor muy útil, si tiene un "acceso aleatorio" cerca del acceso vinculado, hay una variedad de ejemplos cuando necesita ambos accesos, dependiendo de qué punto de tiempo de ejecución.
¿Es esto puramente base en su opinión o ha creado un buen escenario de prueba, donde muestra que su implementación personalizada de 'std :: list
- 1. Por qué no hay una función estándar memswap
- 2. ¿Por qué no hay un estándar de expresión regular?
- 3. ¿Por qué no hay Object.setPrototypeOf (...) en el estándar ECMAScript?
- 4. ¿Por qué no hay operador || = en C/C++?
- 5. operador de python, no hay operador para "no entrar"
- 6. ¿Por qué no hay un estándar común de códec de video HTML5 para todos los navegadores?
- 7. ¿Por qué hay un operador sizeof ... en C++ 0x?
- 8. ¿Por qué no agregaron una versión de operador de iota?
- 9. ¿Por qué debería/no debería usar el operador "nuevo" para instanciar una clase, y por qué?
- 10. ¿Por qué no hay un método Linq para devolver valores distintos por un predicado?
- 11. ¿Por qué CPython no usa `sphinx.autodoc` para la biblioteca estándar?
- 12. Borrado de un estándar :: vector necesita un operador de asignación. ¿Por qué?
- 13. ¿Por qué no hay matrices inmutables en la biblioteca estándar scala?
- 14. ¿Hay una representación estándar para formularios HTML?
- 15. Android: ¿por qué no hay maxHeight para una vista?
- 16. ¿Por qué no hay Xcode para Windows?
- 17. ¿Por qué no hay una fórmula PHP "oficial" para Homebrew?
- 18. ¿Por qué aún no hay una mod_ruby viable para Apache?
- 19. ¿Hay un caso para un operador String.IsNullOrEmpty?
- 20. ¿Por qué no hay un String # shift()?
- 21. por qué no hay sizeof en java
- 22. ¿Por qué no hay métodos para Vector (como toList, toArray) en tipos de colección estándar?
- 23. ¿Hay un operador no (!) En regexp?
- 24. ¿Por qué no hay un método getContentView() para la actividad?
- 25. ¿Por qué el operador + no cambia una lista mientras que .append() lo hace?
- 26. ¿Por qué no hay un documento.createHTMLNode()?
- 27. ¿Por qué no está utilizando mi operador sobrecargado para ++?
- 28. Utiliza (o define) anotaciones no estándar, y por qué motivo. ¿Qué hay de las anotaciones recursivas?
- 29. ¿Hay un operador "no igual" en Python?
- 30. ¿Por qué no hay un método Convert.toFloat()?
Entonces, básicamente, ¿solo se trata de evitar que la gente cometa errores? –
sí.O de no hacer promesas que no puedes cumplir. En el STL, el operador [] promete * acceso * eficiente a elementos arbitrarios. – jalf
¡Y gracias Pavel por la referencia estándar de C++! –