¿Contenedores STL o Qt?

185

¿Cuáles son los pros y los contras del uso de contenedores (Qt QMap, QVectoretc.) sobre su equivalente STL?

Puedo ver una razón para preferir Qt:

  • Los contenedores Qt se pueden pasar a otras partes de Qt. Por ejemplo, se pueden usar para rellenar ay QVariantluego a QSettings(aunque con alguna limitación, solo QListy QMap/ QHashcuyas claves son cadenas son aceptadas).

¿Hay alguna otra?

Editar : Suponiendo que la aplicación ya se basa en Qt.

Julien-L
fuente

Respuestas:

135

Comencé usando std::(w)stringy los contenedores STL exclusivamente y convirtiendo a / desde los equivalentes de Qt, pero ya he cambiado QStringy descubro que estoy usando cada vez más los contenedores de Qt.

Cuando se trata de cadenas, QStringofrece una funcionalidad mucho más completa en comparación con std::basic_stringy es completamente consciente de Unicode. También ofrece una implementación eficiente de COW , en la que he llegado a confiar mucho.

Contenedores de Qt:

  • ofrecen la misma implementación de COW que en QString, lo cual es extremadamente útil cuando se trata de usar la foreachmacro de Qt (que hace una copia) y cuando se usan metatipos o señales y ranuras.
  • puede usar iteradores de estilo STL o iteradores de estilo Java
  • son transmisibles con QDataStream
  • se usan ampliamente en la API de Qt
  • tener una implementación estable en todos los sistemas operativos. Una implementación STL debe obedecer el estándar C ++, pero por lo demás es libre de hacer lo que le plazca (vea la std::stringcontroversia COW). Algunas implementaciones de STL son especialmente malas.
  • proporcionar hashes, que no están disponibles a menos que use TR1

El QTL tiene una filosofía diferente a la del STL, que J. Blanchette resume bien : "Mientras que los contenedores de STL están optimizados para la velocidad bruta, las clases de contenedores de Qt se han diseñado cuidadosamente para proporcionar comodidad, un uso mínimo de memoria y una expansión mínima del código".
El enlace anterior proporciona más detalles sobre la implementación de QTL y las optimizaciones que se utilizan.

rpg
fuente
12
En el nuevo estándar c ++ 0x COW está prácticamente fuera de la mesa.
16
re: "cuidadosamente diseñado para proporcionar [...] un uso mínimo de memoria". No deberías creer en el marketing. Perfil QList<double>en una arquitectura de 32 bits para uso de memoria para ver por ti mismo.
Marc Mutz - mmutz
11
"También ofrece una implementación eficiente de COW": COW no es tan eficiente cuando se trata de aplicaciones multiproceso ...
Grizzly
55
@ MarcMutz-mmutz intenta hacer un perfil en QVectorlugar de QList. Hay una bonita explicación de Qt, que QList está diseñado para almacenar punteros en objetos. Por lo tanto, cada elemento doble creado dinámicamente y puntero a este elemento se almacena en QList. QList está diseñado como contenedor "intermedio" entre el vector y la lista vinculada. No está diseñado para casos críticos de memoria / rendimiento.
Dmitry Sazonov
2
@ user1095108 No hay nada de malo en eso. Ve a usar el stl. Algunos de nosotros preferimos escribir el código correcto rápidamente. No hay nada malo con eso tampoco.
weberc2
178

Esta es una pregunta difícil de responder. Realmente puede reducirse a un argumento filosófico / subjetivo.

Habiendo dicho eso...

Recomiendo la regla "Cuando en Roma ... Haz lo que hacen los romanos"

Lo que significa que si estás en tierra Qt, codifica como lo hacen los Qt'ians. Esto no es solo por cuestiones de legibilidad / consistencia. Considere lo que sucede si almacena todo en un contenedor stl y luego tiene que pasar todos esos datos a una función Qt. ¿Realmente desea administrar un montón de código que copia cosas dentro / fuera de los contenedores Qt? Su código ya depende en gran medida de Qt, por lo que no es como si lo estuviera haciendo más "estándar" utilizando contenedores stl. ¿Y cuál es el objetivo de un contenedor si cada vez que desea usarlo para algo útil, tiene que copiarlo en el contenedor Qt correspondiente?

Doug T.
fuente
1
+1 tienes toda la razón, eso es lo que intenté explicar en mi pregunta ("Puedo ver una razón para preferir Qt"), así que lo edité un poco. Gracias
Julien-L el
Absolutamente bien dicho. Si estás haciendo QT, ¡usa el material QT! Imagine el momento "WTF" para el mantenedor cuando abre una aplicación QT y ve que QT y STL se usan indistintamente. Eso podría terminar siendo una pesadilla (innecesaria).
EsPete
55
@ It'sPete STL es parte del estándar; QT no lo es. Cualquier código que utilice el estándar nunca debe activar un momento "WTF".
Alice
66
Los romanos pusieron a sus cautivos en el Coliseo y luego los cazaron con leones. Si sabe mejor, no siga los hábitos locales. Eso es tan cierto en Qt como lo hubiera sido para el Hombre Moderno en el Imperio Romano ...
Marc Mutz - mmutz
1
@mmutz, dices que como si fuera algo malo, me gustaría poner algo de código que encontré en ese Coliseo y ver el programa
desde el
65

Los contenedores Qt son más limitados que los STL. Algunos ejemplos de donde los STL son superiores (todos estos los he golpeado en el pasado):

  • STL está estandarizado, no cambia con todas las versiones de Qt (Qt 2 tenía QList(basado en puntero) y QValueList(basado en valor); Qt 3 tenía QPtrListy QValueList; Qt 4 ahora tiene QList, y no es nada parecido QPtrList o QValueList ).
    Incluso si termina usando los contenedores Qt, use el subconjunto de API compatible con STL (es decir push_back(), no append();, front()no first(), ...) para evitar la transferencia una vez más, venga Qt 5. Tanto en Qt2-> 3 como en Qt3-> 4 transiciones, los cambios en los contenedores Qt se encontraban entre los que requerían la mayor rotación de código.
  • Todos los contenedores bidireccionales STL tienen rbegin()/ rend(), lo que hace que la iteración inversa sea simétrica a la iteración directa. No todos los contenedores Qt los tienen (los asociativos no), por lo que la iteración inversa es innecesariamente complicada.
  • Los contenedores STL tienen un rango insert()de tipos de iteradores diferentes, pero compatibles, lo que hace que sea std::copy()mucho menos necesario.
  • Los contenedores STL tienen un Allocatorargumento de plantilla, lo que hace que la administración de memoria personalizada sea trivial (se requiere typedef), en comparación con Qt (se QLineEditrequiere fork de s/QString/secqstring/). EDITAR 20171220 : Esto corta Qt de los avances en el diseño del asignador después de C ++ 11 y C ++ 17, cf. por ejemplo, la charla de John Lakos ( parte 2 ).
  • No hay Qt equivalente a std::deque.
  • std::listtiene splice(). Cada vez que me encuentro usando std::list, es porque lo necesito splice().
  • std::stack, std::queueAgregar adecuadamente su contenedor subyacente, y no heredan, como QStack, QQueuehacer.
  • QSetes como std::unordered_set, no es así std::set.
  • QListes un simplemente extraño .

Muchos de los anteriores podrían resolverse fácilmente en Qt , pero la biblioteca de contenedores en Qt parece experimentar una falta de enfoque de desarrollo en este momento.

EDITAR 20150106 : Después de pasar un tiempo tratando de llevar el soporte C ++ 11 a las clases de contenedores Qt 5, he decidido que no vale la pena el trabajo. Si observa el trabajo que se está poniendo en las implementaciones de la biblioteca estándar de C ++, está bastante claro que las clases Qt nunca se pondrán al día. Hemos lanzado Qt 5.4 ahora yQVector todavía no mueve elementos en reasignaciones, no tieneemplace_back()o rvalue-push_back()... También recientementerechazamosunaQOptionalplantilla de clase, esperando en sustd::optionallugar. Del mismo modo parastd::unique_ptr. Espero que esa tendencia continúe.

Marc Mutz - mmutz
fuente
3
Huh Tenía la impresión de que QList era el equivalente a std::deque. Claramente, no debería haber simplemente hojeado la documentación.
Dennis Zickefoose
QVectorha tenido crbeginy amigos desde Qt 5.6
Bart Louwers
@Alex: derecha, añadí los fáciles, pero no todos los contenedores Qt ellos tienen, sin embargo, (porque no se utiliza std::reverse_iteratordurante los rotos QHash/ QMapiteradores, que, cuando se eliminan las referencias, regresan mapped_typeen lugar de value_type). Nada que no se pueda arreglar, pero vea mi EDIT de 2015.
Marc Mutz - mmutz
@ MarcMutz-mmutz Gracias por aclarar.
Bart Louwers
Puede valer la pena agregar a la lista el hecho de que, por ejemplo, se QVectorutiliza intcomo índice, lo que limita los tamaños de 31 bits (incluso en sistemas de 64 bits). Además, ni siquiera puede almacenar INT_MAXelementos de tamaño superior a 1 byte. Por ejemplo, el más grande .size()que pude tener QVector<float>en x86_64 Linux gcc fue 536870907 elementos (2²⁹-5), mientras que asigné con std::vector<float>éxito 4294967295 elementos (2³²-1; no intenté más debido a la falta de RAM para esto (este tamaño ya toma 16 GiB) )
Ruslan
31

Dividamos estas afirmaciones en fenómenos mensurables reales:

  • Más ligero: los contenedores Qt usan menos memoria que los contenedores STL
  • Más seguro: los contenedores Qt tienen menos oportunidades de ser utilizados incorrectamente
  • Más fácil: los contenedores Qt presentan menos carga intelectual

Más fácil

La afirmación hecha en este contexto es que la iteración de estilo java es de alguna manera "más fácil" que el estilo STL y, por lo tanto, Qt es más fácil de usar debido a esta interfaz adicional.

Estilo Java

QListIterator<QString> i(list);
while (i.hasNext())
    qDebug() << i.next();

Estilo STL:

QList<QString>::iterator i;
for (i = list.begin(); i != list.end(); ++i)
    qDebug << *i;

El estilo de iterador de Java tiene la ventaja de ser un poco más pequeño y limpio. El problema es que esto ya no es en realidad estilo STL.

Estilo C ++ 11 STL

for( auto i = list.begin(); i != list.end(); ++i)
    qDebug << *i;

o

C ++ 11 estilo foreach

for (QString i : list)
    qDebug << i;

Lo cual es tan drásticamente simple que no hay razón para usar otra cosa (a menos que no sea compatible con C ++ 11).

Mi favorito, sin embargo, es:

BOOST_FOREACH(QString i, list)
{
    qDebug << i;
}

Entonces, como podemos ver, esta interfaz no nos aporta nada más que una interfaz adicional, además de una interfaz ya elegante, optimizada y moderna. ¿Agregar un nivel innecesario de abstracción sobre una interfaz ya estable y utilizable? No es mi idea de "más fácil".

Además, las interfaces Qt foreach y java agregan sobrecarga; copian la estructura y proporcionan un nivel innecesario de indirección. Puede que esto no parezca mucho, pero ¿por qué agregar una capa de sobrecarga para proporcionar una interfaz no tan simple? Java tiene esta interfaz porque Java no tiene sobrecarga del operador; C ++ hace.

Más seguro

La justificación que da Qt es el problema de compartir implícitamente, que no es ni implícito ni un problema. Sin embargo, implica compartir.

QVector<int> a, b;
a.resize(100000); // make a big vector filled with 0.

QVector<int>::iterator i = a.begin();
// WRONG way of using the iterator i:
b = a;
/*
Now we should be careful with iterator i since it will point to shared data
If we do *i = 4 then we would change the shared instance (both vectors)
The behavior differs from STL containers. Avoid doing such things in Qt.
*/

Primero, esto no es implícito; Usted está asignando explícitamente un vector a otro. La especificación del iterador STL indica claramente que los iteradores pertenecen al contenedor, por lo que claramente hemos introducido un contenedor compartido entre by a. Segundo, esto no es un problema; siempre y cuando se sigan todas las reglas de la especificación del iterador, absolutamente nada saldrá mal. La única vez que algo sale mal es aquí:

b.clear(); // Now the iterator i is completely invalid.

Qt especifica esto como si significara algo, como un problema surge de novo de este escenario. No lo hace. El iterador está invalidado, y al igual que cualquier cosa a la que se pueda acceder desde múltiples áreas disjuntas, así es como funciona. De hecho, esto ocurrirá fácilmente con los iteradores de estilo Java en Qt, gracias a su gran dependencia del intercambio implícito, que es un antipatrón como se documenta aquí , y en muchas otras áreas . Parece especialmente extraño que esta "optimización" se ponga en uso en un marco que se mueve cada vez más hacia el subprocesamiento múltiple, pero eso es marketing para usted.

Encendedor

Este es un poco más complicado. El uso de estrategias de copia y escritura y uso compartido implícito y crecimiento hace que sea muy difícil garantizar la cantidad de memoria que usará su contenedor en un momento dado. Esto es diferente al STL, que le brinda fuertes garantías algorítmicas.

Sabemos que el límite mínimo de espacio desperdiciado para un vector es la raíz cuadrada de la longitud del vector , pero parece que no hay forma de implementar esto en Qt; las diversas "optimizaciones" que admiten impedirían esta característica tan importante de ahorro de espacio. El STL no requiere esta característica (y la mayoría usa un crecimiento doble, que es más derrochador), pero es importante tener en cuenta que al menos podría implementar esta característica, si es necesario.

Lo mismo se aplica a las listas doblemente enlazadas, que podrían usar enlaces XOr para reducir drásticamente el espacio utilizado. Nuevamente, esto es imposible con Qt, debido a sus requisitos de crecimiento y VACA.

De hecho, COW puede hacer algo más liviano, pero también lo pueden hacer los Intrusive Containers, como los respaldados por boost , y Qt los usó con frecuencia en las versiones anteriores, pero ya no se usan tanto porque son difíciles de usar, inseguros e imponen una carga en el programador. COW es una solución mucho menos intrusiva, pero poco atractiva por las razones planteadas anteriormente.

No hay ninguna razón por la que no pueda usar contenedores STL con el mismo costo de memoria o menos que los contenedores de Qt, con el beneficio adicional de saber realmente cuánta memoria perderá en un momento dado. Desafortunadamente, es imposible comparar los dos en el uso de la memoria sin procesar, porque tales puntos de referencia mostrarían resultados muy diferentes en diferentes casos de uso, que es el tipo exacto de problema que el STL fue diseñado para corregir.

En conclusión

Evite el uso de Qt Containers cuando sea posible hacerlo sin imponer un costo de copia, y use la iteración de tipo STL (tal vez a través de un contenedor o la nueva sintaxis), siempre que sea posible.

Alicia
fuente
44
Sus puntos son en gran medida válidos, pero hay información engañosa allí: Adding an unnecessary level of abstraction on top of an already stable and usable interface? Not my idea of "easier".los iteradores de estilo Java de Qt no se agregaron a C ++ 11; Lo preceden. De todos modos, Qt's foreach(QString elem, list)es tan fácil como el foreach de C ++ 11 o BOOST_FOREACH y funciona con compiladores anteriores a C ++ 11.
weberc2
@ weberc2 Estás confundido; Los iteradores de estilo Java de Qt se agregan encima de los iteradores C ++ (no C ++ 11). Es una capa adicional de abstracción (y una innecesaria) que hincha la interfaz, lo que no es más fácil. Y foreach para Qt no es tan fácil como BOOST_FOREACH, ya que notablemente no es tan seguro y no tiene la misma amplitud de soporte (BOOST_FOREACH puede aplicarse a cualquier rango, para cualquier versión de C ++, donde foreach en QT exige C + +03 cumplimiento). El foreach de QT debe evitarse a toda costa.
Alice
So, as we can see, this interface gains us nothing except an additional interface, *on top of* an already sleek, streamlined, and modern interface. Adding an unnecessary level of abstraction on top of an already stable and usable interface? Not my idea of "easier".(énfasis mío) Dijiste esto justo después de mostrarnos las versiones C ++ 11 y BOOST de foreach, haciendo que parezca que la versión Qt está construida a partir de uno de esos dos, lo cual no es el caso AFAICT. Estoy seguro de que eso no es lo que querías decir, pero así es como sale. De ahí la "información engañosa".
weberc2
It's an additional layer of abstraction (and an unnecessary one) that bloats the interface, which is not easier.Todavía no está claro con qué te estás comparando. C ++ 03 iteradores? C ++ 11 iteradores? BOOST_FOREACH? Todas las anteriores?
weberc2
1
Solo digo que a menudo eres muy ambiguo en cuanto a qué método de iteración te refieres. Creo que crees que eres claro y tu lenguaje es razonable, pero parece extraño negarse a especificar. Estoy de acuerdo en estar en desacuerdo, supongo.
weberc2 01 de
23

Contenedores STL:

  • Tener garantías de desempeño
  • Se puede usar en algoritmos STL que también tienen garantías de rendimiento
  • Puede ser aprovechado por bibliotecas de C ++ de terceros como Boost
  • Son estándar y es probable que superen las soluciones patentadas.
  • Fomentar la programación genérica de algoritmos y estructuras de datos. Si escribe nuevos algoritmos y estructuras de datos que se ajustan a STL, puede aprovechar lo que STL ya proporciona sin costo alguno.
fbrereto
fuente
55
Todo lo anterior, excepto ser un estándar, también es válido para QTL, siempre que compile Qt con soporte STL (el valor predeterminado). El soporte STL incluye funciones iteradoras, definiciones de tipo de contenedor (const_iterator, etc.), funciones de conversión (hacia / desde STL).
RPG
2
Qt no es propietario
txwikinger
3
@rpg Casi todos ellos no son ciertos de QTL; QTL no tiene garantías sólidas de rendimiento (ya que las rompieron fácilmente en el pasado), no cumplen con STL (sin reversa y, por lo tanto, no pueden ser utilizadas por mucho impulso), no son estándar (cambian constantemente entre versiones) y lo hacen no fomenta la programación genérica (por ejemplo, no tienen argumentos de plantilla para asignadores).
Alice
15

Los contenedores Qt usan modismos de copia en escritura.

TimW
fuente
2
+1, podría ser una ventaja significativa en rendimiento y recursos
RedGlyph
32
O podría ser una desventaja significativa. Ver gotw.ca/publications/optimizations.htm
Kaz Dragon el
3
La cuenta atómica parece funcionar bastante bien: labs.trolltech.com/blogs/2006/10/16/…
rpg el
Los contenedores STL son libres de usar cualquier idioma que exista siempre que cumplan con sus garantías de rendimiento y las especificaciones. COW es válido, incluso bajo C ++ 11 / C ++ 14 STL.
Alice
1
@Alice COW no es una implementación válida la mayor parte del tiempo porque rompe la complejidad del estándar y las garantías de validez del iterador en casi cualquier caso. Una de las pocas clases que se pudo implementar con COW fue std::basic_stringy el estándar tomó medidas con C ++ 11 para que esto no sea conforme.
Tiago Gomes
9

Uno de los principales problemas es que la API de Qt espera que proporciones datos en los contenedores de Qt, por lo que también puedes usar los contenedores de Qt en lugar de transformarte de un lado a otro.

Además, si ya está utilizando los contenedores Qt, podría ser un poco más óptimo usarlos exclusivamente, ya que no tendría que incluir los archivos de encabezado STL y posiblemente vincularlos en las bibliotecas STL. Sin embargo, dependiendo de su cadena de herramientas, eso puede suceder de todos modos. Puramente desde una perspectiva de diseño, la consistencia generalmente es algo bueno.

qid
fuente
1
La velocidad a la que debe "transformarse de un lado a otro" entre los contenedores STL y Qt en una aplicación real que usa STL, excepto cuando la interfaz con Qt generalmente se sobreestima en gran medida. La mayoría de las veces haces algo de std :: transform que viene hacia / desde la capa de presentación (que usa Qt) y obtienes el cambio de contenedor gratis. Las partes interesadas pueden navegar a projects.kde.org/projects/kde/kdepim/repository/revisions/… para ver por sí mismos.
Marc Mutz - mmutz
8

Si los datos con los que está trabajando se utilizan principalmente para controlar la interfaz de usuario basada en Qt, definitivamente use contenedores Qt.

Si los datos se usan principalmente internamente en la aplicación, y nunca es probable que se aleje de Qt, entonces, salvo problemas de rendimiento, use los contenedores de Qt porque hará que los bits de datos que van a la interfaz de usuario sean más fáciles de manejar.

Si los datos se usan principalmente junto con otras bibliotecas que solo conocen los contenedores STL, entonces use contenedores STL. Si tiene esta situación, está en problemas, pase lo que pase, ya que va a hacer muchos cambios de un lado a otro entre los tipos de contenedores, sin importar lo que haga.

Michael Kohne
fuente
7

Además de la diferencia de COW, los contenedores STL son mucho más compatibles en una variedad de plataformas. Qt es lo suficientemente portátil si limita su trabajo a plataformas "convencionales", pero el STL también está disponible en muchas otras plataformas más oscuras (por ejemplo, los DSP de Texas Instruments).

Debido a que el STL es estándar en lugar de estar controlado por una sola corporación, en general, hay más programadores que pueden leer, comprender y modificar fácilmente el código STL y más recursos (libros, foros en línea, conferencias, etc.) para apoyarlos en haciendo esto que hay para Qt. Eso no quiere decir que uno deba rehuir Qt solo por esta razón; solo que, si todas las demás cosas son iguales, debe usar el STL de manera predeterminada, pero, por supuesto, todas las cosas rara vez son iguales, por lo que tendrá que decidir en su propio contexto cuál tiene más sentido.

Con respecto a la respuesta de AlexKR: el rendimiento de STL está garantizado dentro de los límites, pero una implementación dada puede hacer uso de detalles dependientes de la plataforma para acelerar su STL. Entonces, en ese sentido, puede obtener resultados diferentes en diferentes plataformas, pero nunca será más lento que la garantía explícita (errores de módulo).

metal
fuente
9
Con respecto a su primer punto: supongo que el OP se refiere a proyectos que ya usan Qt y, por lo tanto, ya están limitados a plataformas "convencionales". Parece poco probable que alguien obtenga una biblioteca tan pesada como Qt solo por sus clases de contenedor.
ThisSuitIsBlackNot
4

Mis cinco centavos: se supone que los contenedores Qt funcionan de manera similar en diferentes plataformas. Mientras que los contenedores STL dependen de la implementación de STL. Es posible que obtenga resultados de rendimiento diferentes.

EDITAR: No estoy diciendo que STL es "más lento", pero señalo los efectos de varios detalles de implementación.
Por favor verifique esto , y luego tal vez esto .
Y no es un problema real de STL. Obviamente, si tiene una diferencia significativa en el rendimiento, entonces hay un problema en el código que usa STL.

alexkr
fuente
Los contenedores STL son todos similares, independientemente de la implementación. No puede tener un vector implementado como una lista detrás de escena, ya que tiene que estar en un bloque contiguo de memoria. El STL también suele estar optimizado en gran medida en todas las plataformas principales.
Yacoby el
1
Si se apega a lo que promete STL (en lugar de asumir cómo se implementa), nunca tendrá problemas para moverse entre plataformas con STL. Lo mismo con Qt.
Michael Kohne el
Esto es exactamente lo contrario de verdad. Los contenedores STL siempre funcionan igual en todas las plataformas; si no lo hacen, no son STL. Sin embargo, QT cambia drásticamente el rendimiento de una versión a otra, por lo que en una plataforma con QT4.0 en lugar de QT4.8, puede obtener algunos cambios serios.
Alice
1
Estás confundiendo dos tipos muy diferentes de rendimiento; rendimiento algorítmico y rendimiento computacional práctico. Todas las implementaciones de STL garantizan el mismo rendimiento algorítmico; Si su vector toma tiempo log (n) para indexar un elemento, no es un vector STL. Sus enlaces apuntan a un rendimiento computacional práctico, que no tiene sentido en esta discusión; QT cambia sus algoritmos entre versiones, y el mismo C ++ en diferentes plataformas obtiene un rendimiento diferente. Estos son, en mi experiencia, mucho más maleables que las diferencias en el rendimiento de STL.
Alice
3

Supongo que depende de la forma en que uses Qt. Si lo usa en todo su producto, entonces probablemente tenga sentido usar contenedores Qt. Si lo contiene solo (por ejemplo) en la parte de la interfaz de usuario, puede ser mejor usar contenedores estándar de C ++.

Nemanja Trifunovic
fuente
3

Soy de la opinión de que STL es una excelente pieza de software, sin embargo, si debo hacer alguna programación relacionada con KDE o Qt, entonces Qt es el camino a seguir. También depende del compilador que esté utilizando, con GCC STL funciona bastante bien, sin embargo, si tiene que usar, por ejemplo, SUN Studio CC, es probable que STL le traiga dolores de cabeza debido al compilador, no al STL per se. En ese caso, dado que el compilador te hará daño en la cabeza, solo usa Qt para ahorrarte el problema. Solo mis 2 centavos ...

Paulo Lopes
fuente
3

Hay una (a veces) gran limitación en QVector. Solo puede asignar bytes int de memoria (tenga en cuenta que el límite está en bytes no en número de elementos). Esto implica que intentar asignar bloques contiguos de memoria mayores de ~ 2GB con un QVector provocará un bloqueo. Esto sucede con Qt 4 y 5. std :: vector no tiene esa limitación.

fedemp
fuente
0

La razón principal para usar contenedores STL para mí es si necesita un asignador personalizado para reutilizar la memoria en contenedores muy grandes. Supongamos, por ejemplo, que tiene un QMap que almacena 1000000 entradas (pares clave / valor). En Qt eso implica exactamente 1000000 millones de asignaciones (new llamadas) pase lo que pase. En STL, siempre puede crear un asignador personalizado que asigne internamente toda esa memoria a la vez y asignarlo a cada entrada a medida que se llena el mapa.

Mi consejo es usar contenedores STL al escribir algoritmos críticos de rendimiento en la lógica de negocios y luego convertirlos nuevamente a contenedores Qt cuando los resultados estén listos para que los muestren los controles y formularios de la IU si es necesario.

Darien Pardinas
fuente
No estoy tratando de defender el QTL aquí, pero podrías especializarte QMapNode<K,V>en tu K, Vpara proporcionar el tuyo propio operator new.
Marc Mutz - mmutz