Contentores STL ou Qt?

185

Quais são as vantagens e desvantagens de utilizar recipientes Qt ( QMap, QVector, etc.) sobre a sua STL equivalente?

Eu posso ver um motivo para preferir o Qt:

  • Os contêineres de Qt podem ser repassados ​​para outras partes do Qt. Por exemplo, eles podem ser usados ​​para preencher um QVariante depois um QSettings(com algumas limitações, apenas QListe QMap/ QHashcujas chaves são cadeias de caracteres são aceitos).

Existe algum outro?

Edit : Supondo que o aplicativo já dependa do Qt.

Julien-L
fonte

Respostas:

135

Comecei usando std::(w)stringexclusivamente os contêineres STL e convertendo para / dos equivalentes Qt, mas já mudei para QStringe acho que estou usando os contêineres do Qt cada vez mais.

Quando se trata de strings, QStringoferece uma funcionalidade muito mais completa em comparação com std::basic_stringe é totalmente compatível com Unicode. Ele também oferece uma implementação eficiente de COW , na qual eu dependo fortemente.

Contentores da Qt:

  • oferecem a mesma implementação de COW que em QString, o que é extremamente útil quando se trata de usar a foreachmacro do Qt (que faz uma cópia) e ao usar meta-tipos ou sinais e slots.
  • pode usar iteradores no estilo STL ou iteradores no estilo Java
  • são streamable com QDataStream
  • são usados ​​extensivamente na API do Qt
  • ter uma implementação estável nos sistemas operacionais. Uma implementação de STL deve obedecer ao padrão C ++, mas é livre de fazer o que bem entender (consulte a std::stringcontrovérsia da COW). Algumas implementações de STL são especialmente ruins.
  • fornecer hashes, que não estão disponíveis, a menos que você use TR1

O QTL tem uma filosofia diferente da STL, que é bem resumida por J. Blanchette: "Enquanto os contêineres da STL são otimizados para velocidade bruta, as classes de contêineres da Qt foram cuidadosamente projetadas para oferecer conveniência, uso mínimo de memória e expansão mínima de código".
O link acima fornece mais detalhes sobre a implementação do QTL e quais otimizações são usadas.

rpg
fonte
12
No novo padrão, o c ++ 0x COW está praticamente fora de questão.
16
re: "cuidadosamente projetado para fornecer [...] uso mínimo de memória". Você não deveria acreditar em marketing. Perfil QList<double>em uma arquitetura de 32 bits para o uso da memória ver por si mesmo.
Marc Mutz - mmutz
11
"Ele também oferece uma implementação COW eficiente": vaca não é tão eficiente quando se trata de aplicativos multithreaded ...
Grizzly
5
@ MarcMutz-mmutz tenta criar um perfil em QVectorvez de QList. Há uma explicação bastante do Qt, que o QList foi projetado para armazenar ponteiros nos objetos. Portanto, cada item duplo criado dinamicamente e ponteiro para esse item são armazenados QList. O QList foi projetado como contêiner "intermediário" entre o vetor e a lista vinculada. Ele não foi projetado para casos críticos de memória / desempenho.
Dmitry Sazonov
2
@ user1095108 Não há nada de errado nisso. Vá usar o stl. Alguns de nós preferem escrever o código correto rapidamente. Também não há nada de errado nisso.
weberc2
178

Esta é uma pergunta difícil de responder. Pode realmente se resumir a um argumento filosófico / subjetivo.

Dito isto ...

Eu recomendo a regra "Quando em Roma ... faça como os romanos"

O que significa que se você estiver na terra Qt, codifique como os Qt'ians fazem. Isso não é apenas para questões de legibilidade / consistência. Considere o que acontece se você armazenar tudo em um contêiner stl, então você precisará passar todos esses dados para uma função Qt. Deseja realmente gerenciar um monte de código que copia as coisas para dentro / fora dos contêineres Qt. Seu código já é fortemente dependente do Qt, então não é como se você o estivesse tornando mais "padrão" usando stl containers. E qual é o sentido de um contêiner, se toda vez que você quiser usá-lo para algo útil, você deve copiá-lo no contêiner Qt correspondente?

Doug T.
fonte
1
Com +1 você está totalmente certo, foi o que tentei explicar na minha pergunta ("Posso ver um motivo para preferir o Qt"), então editei um pouco. Obrigado
Julien-L
Absolutamente bem dito. Se você estiver fazendo QT, use o material QT! Imagine o momento "WTF" para o mantenedor quando ele abre um aplicativo QT e vê QT e STL usados ​​de forma intercambiável. Isso pode acabar sendo um pesadelo (desnecessário).
It'sPete
5
@ It'sPete STL faz parte do padrão; QT não é. Qualquer código que faça uso do padrão nunca deve acionar um momento "WTF".
Alice
6
Os romanos colocaram seus cativos no Coliseu e os caçaram com leões. Se você conhece melhor, não siga os hábitos locais. Isso é tão verdadeiro em Qt como teria sido para o homem moderno, no Império Romano ...
Marc Mutz - mmutz
1
@mmutz você diz isso como se fosse uma coisa ruim, eu gostaria de colocar algum código que eu encontrei em que Coliseu e assistir ao show
SLF
65

Os contêineres Qt são mais limitados que os contêineres STL. Alguns exemplos de onde os STL são superiores (todos esses que eu bati no passado):

  • O STL é padronizado, não muda com todas as versões do Qt (o Qt 2 tinha QList(com base em ponteiro) e QValueList(com base em valor); o Qt 3 tinha QPtrListe QValueList; o Qt 4 agora tem QList, e não é nada parecido QPtrList ou QValueList ).
    Mesmo se você acabar usando os contêineres Qt, use o subconjunto da API compatível com STL (ou seja push_back(), não append();, front()não first(), ...) para evitar a portabilidade novamente, venha o Qt 5. Nos Qt2-> 3 e Qt3-> 4 nas transições, as alterações nos contêineres Qt estavam entre as que mais exigiam rotatividade de código.
  • Todos os contêineres bidirecionais da STL têm rbegin() / rend(), tornando a iteração reversa simétrica para a iteração direta. Nem todos os contêineres Qt os possuem (os associativos não), portanto, a iteração reversa é desnecessariamente complicada.
  • Os contêineres STL variam insert()entre diferentes, mas compatíveis, tipos de iteradores, tornandostd::copy() muito menos necessário.
  • Os contêineres STL têm um Allocatorargumento de modelo, tornando trivial o gerenciamento de memória personalizado (é necessário typedef), em comparação com o Qt (bifurcação de QLineEditnecessário para s/QString/secqstring/). EDIT 20171220 : Isso reduz Qt dos avanços no design do alocador, seguindo C ++ 11 e C ++ 17, cf. por exemplo, a palestra de John Lakos ( parte 2 ).
  • Não existe um Qt equivalente a std::deque.
  • std::listtem splice(). Sempre que me vejo usando std::list, é porque preciso splice().
  • std::stack, std::queueAgregar adequadamente o seu recipiente subjacente, e não herdam-lo, como QStack, QQueuefazer.
  • QSeté como std::unordered_set, não como std::set.
  • QListé um pouco estranho .

Muitos dos itens acima podem ser resolvidos com bastante facilidade no Qt , mas a biblioteca de contêineres no Qt parece experimentar uma falta de foco no desenvolvimento no momento.

EDIT 20150106 : Depois de passar algum tempo tentando levar o suporte ao C ++ 11 para as classes de contêineres do Qt 5, decidi que não vale a pena o trabalho. Se você observar o trabalho que está sendo colocado nas implementações de bibliotecas padrão do C ++, é bastante claro que as classes Qt nunca serão atualizadas. Lançamos o Qt 5.4 agora eQVector ainda não movemos elementos nas realocações, não tememplace_back()ou rvalorizamospush_back()... Também rejeitamos recentemente umQOptionalmodelo de classe, esperando porstd::optionalele. Da mesma forma parastd::unique_ptr. Espero que essa tendência continue.

Marc Mutz - mmutz
fonte
3
Hã. Eu estava com a impressão de que QList era o equivalente a std::deque. Claramente, eu não deveria ter apenas folheado a documentação.
Dennis Zickefoose
QVectorteve crbegine amigos desde Qt 5.6
Bart Louwers
@ Alex: certo, eu adicionei os mais fáceis, mas nem todos os contêineres Qt ainda os possuem (porque você não usa std::reverse_iteratorsobre os quebrados QHash/ QMapiteradores, que, quando desreferenciados, retornam em mapped_typevez de value_type). Nada que não possa ser consertado, mas veja a minha edição de 2015.
Marc Mutz #: mmutz
@ MarcMutz-mmutz Obrigado por esclarecer.
Bart Louwers
Pode valer a pena acrescentar à lista o fato de, por exemplo, QVectorusar intcomo índice, limitando os tamanhos de 31 bits (mesmo em sistemas de 64 bits). Além disso, ele não pode nem armazenar INT_MAXelementos de tamanho maior que 1 byte. Por exemplo, o maior que .size()eu poderia ter QVector<float>no x86_64 gcc no Linux era 536870907 elementos (2²⁹-5), enquanto alocava com std::vector<float>sucesso 4294967295 elementos (2³²-1; não tentei mais devido à falta de RAM para isso (esse tamanho já leva 16 GiB) )
Ruslan #
31

Vamos dividir essas afirmações em fenômenos mensuráveis ​​reais:

  • Mais leve: os contêineres Qt usam menos memória que os contêineres STL
  • Mais seguro: os contêineres Qt têm menos oportunidade de serem usados ​​indevidamente
  • Mais fácil: os contêineres Qt apresentam menos ônus intelectual

Mais fácil

A alegação feita neste contexto é que a iteração no estilo java é de alguma forma "mais fácil" que o estilo STL e, portanto, o Qt é mais fácil de usar devido a essa interface 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;

O estilo do iterador Java tem o benefício de ser um pouco menor e mais limpo. O problema é que esse não é mais o estilo STL.

Estilo STL C ++ 11

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

ou

Estilo foreach C ++ 11

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

O que é tão drasticamente simples que não há razão para usar qualquer outra coisa (a menos que você não suporte C ++ 11).

Meu favorito, no entanto, é:

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

Portanto, como podemos ver, essa interface não ganha nada além de uma interface adicional, além de uma interface já elegante, simplificada e moderna. Adicionando um nível desnecessário de abstração em cima de uma interface já estável e utilizável? Não é a minha idéia de "mais fácil".

Além disso, as interfaces Qt foreach e java adicionam sobrecarga; eles copiam a estrutura e fornecem um nível desnecessário de indireção. Isso pode não parecer muito, mas por que adicionar uma camada de sobrecarga para fornecer uma interface não muito mais simples? Java possui essa interface porque o java não possui sobrecarga de operador; C ++ faz.

Mais seguro

A justificativa que Qt dá é o problema implícito de compartilhamento, que não é implícito nem é um problema. No entanto, envolve compartilhar.

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.
*/

Primeiro, isso não está implícito; você está atribuindo explicitamente um vetor a outro. A especificação do iterador STL indica claramente que os iteradores pertencem ao contêiner, portanto, introduzimos claramente um contêiner compartilhado entre be um. Segundo, isso não é um problema; contanto que todas as regras da especificação do iterador sejam seguidas, absolutamente nada dará errado. A única vez que algo dá errado é aqui:

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

Qt especifica isso como se isso significasse algo, como se um problema surgisse de novo nesse cenário. Não faz. O iterador é invalidado e, assim como qualquer coisa que possa ser acessada de várias áreas independentes, é assim que funciona. De fato, isso ocorrerá prontamente com os iteradores do estilo Java no Qt, graças à grande dependência do compartilhamento implícito, que é um antipadrão conforme documentado aqui e em muitas outras áreas . Parece especialmente estranho que essa "otimização" seja usada em uma estrutura que se move cada vez mais para o multithreading, mas isso é marketing para você.

Mais leve

Este é um pouco mais complicado. O uso das estratégias de cópia na gravação e compartilhamento implícito e crescimento torna muito difícil garantir realmente a quantidade de memória que seu contêiner usará a qualquer momento. Isso é diferente do STL, que oferece fortes garantias algorítmicas.

Sabemos que o limite mínimo de espaço desperdiçado para um vetor é a raiz quadrada do comprimento do vetor , mas parece não haver maneira de implementar isso no Qt; as várias "otimizações" suportadas impediriam esse recurso muito importante de economia de espaço. O STL não requer esse recurso (e a maioria usa um crescimento de duplicação, o que é mais inútil), mas é importante observar que você poderia pelo menos implementar esse recurso, se necessário.

O mesmo se aplica às listas duplamente vinculadas, que poderiam usar a vinculação XOr para reduzir drasticamente o espaço usado. Novamente, isso é impossível com o Qt, devido a seus requisitos de crescimento e COW.

O COW pode, de fato, tornar algo mais leve, mas o mesmo pode acontecer com os Intrusive Containers, como os suportados pelo boost , e o Qt os usa com frequência nas versões anteriores, mas não são mais usados ​​tanto porque são difíceis de usar, inseguros e impõem um ônus. no programador. COW é uma solução muito menos invasiva, mas pouco atraente pelas razões expostas acima.

Não há razão para que você não possa usar contêineres STL com o mesmo custo de memória ou menos que os contêineres do Qt, com o benefício adicional de saber quanta memória você desperdiçará a qualquer momento. Infelizmente, é impossível comparar os dois no uso de memória bruta, porque esses benchmarks mostrariam resultados bastante diferentes em diferentes casos de uso, que é o tipo exato de problema que o STL foi projetado para corrigir.

Em conclusão

Evite o uso de Qt Containers sempre que possível, sem impor um custo de cópia, e use a iteração do tipo STL (talvez por meio de um wrapper ou da nova sintaxe), sempre que possível.

Alice
fonte
4
Seus pontos são amplamente válidos, mas há algumas informações enganosas: Adding an unnecessary level of abstraction on top of an already stable and usable interface? Not my idea of "easier".os iteradores no estilo Java do Qt não foram adicionados ao C ++ 11; eles são anteriores. De qualquer forma, o Qt foreach(QString elem, list)é tão fácil quanto o foreach do C ++ 11 ou o BOOST_FOREACH e funciona com compiladores compatíveis com o C ++ 11 anterior.
weberc2
@ weberc2 Você está confuso; Os iteradores de estilo Java do Qt são adicionados sobre os iteradores C ++ (não C ++ 11). É uma camada adicional de abstração (e desnecessária) que incha a interface, o que não é mais fácil. E o foreach para Qt não é tão fácil quanto o BOOST_FOREACH, pois não é tão seguro e não possui a mesma amplitude de suporte (o BOOST_FOREACH pode ser aplicado a qualquer intervalo, para qualquer versão do C ++, onde o foreach no QT exige C + +03 conformidade). O foreach do QT deve ser evitado a todo custo.
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".(ênfase minha) Você disse isso logo após nos mostrar as versões C ++ 11 e BOOST do foreach, fazendo parecer que a versão Qt foi criada com base em uma dessas duas, o que não é o caso AFAICT. Tenho certeza de que não foi isso que você quis dizer, mas é assim que acontece. Daí "informações enganosas".
Weberc2
It's an additional layer of abstraction (and an unnecessary one) that bloats the interface, which is not easier.Ainda não está claro o que você está comparando. C ++ 03 iteradores? Iteradores C ++ 11? BOOST_FOREACH? Tudo acima?
weberc2
1
Só estou dizendo que você geralmente é muito ambíguo quanto ao método de iteração que está se referindo. Acredito que você se sinta bem e que seu idioma seja razoável, mas parece estranho recusar-se a especificar. Concordo em discordar, suponho.
precisa saber é o seguinte
23

Contentores STL:

  • Tenha garantias de desempenho
  • Pode ser usado em algoritmos STL que também possuem garantias de desempenho
  • Pode ser aproveitado por bibliotecas C ++ de terceiros como o Boost
  • São padrão e provavelmente sobreviverão a soluções proprietárias
  • Incentivar a programação genérica de algoritmos e estruturas de dados. Se você escrever novos algoritmos e estruturas de dados em conformidade com STL, poderá aproveitar o que a STL já fornece sem nenhum custo.
fbrereto
fonte
5
Todos os itens acima, exceto o padrão, também são verdadeiros para o QTL, desde que você compile o Qt com suporte ao STL (o padrão). O suporte a STL inclui funções de iterador, typedefs de contêiner (const_iterator, etc), funções de conversão (de / para STL).
Rpg
2
Qt não é proprietária
txwikinger
3
@rpg Quase todos eles não são verdadeiros sobre QTL; O QTL não possui fortes garantias de desempenho (como as quebraram prontamente no passado), não são compatíveis com STL (sem reversão e, portanto, não podem ser usadas por muito aumento), não são padrão (elas mudam constantemente entre as versões) e fazem não incentivam a programação genérica (eles não têm argumentos de modelo para alocadores, por exemplo).
Alice
15

Os contêineres Qt usam o idioma de cópia na gravação.

TimW
fonte
2
+1, pode ser uma vantagem significativa no desempenho e recursos
RedGlyph
32
Ou pode ser uma desvantagem significativa. Veja gotw.ca/publications/optimizations.htm
Kaz Dragon
3
O refcount atômica parece se sair muito bem: labs.trolltech.com/blogs/2006/10/16/...
rpg
Os contêineres da STL são livres para usar quaisquer idiomas existentes, desde que atendam às garantias de desempenho e às especificações. COW é válido, mesmo em C ++ 11 / C ++ 14 STL.
Alice
1
O @Alice COW não é uma implementação válida na maioria das vezes, porque quebra a complexidade do padrão e garante a validade do iterador em quase todos os casos. Uma das poucas classes que poderiam ser implementadas com o COW foi std::basic_stringe o padrão tomou ações com o C ++ 11 para tornar isso não conforme.
Tiago Gomes
9

Uma das principais questões é que a API do Qt espera que você forneça dados nos contêineres do Qt; portanto, você também pode simplesmente usar os contêineres do Qt em vez de se alternar entre os dois.

Além disso, se você já estiver usando os contêineres Qt, pode ser um pouco mais ideal usá-los exclusivamente, pois não será necessário incluir os arquivos de cabeçalho STL e potencialmente vincular as bibliotecas STL. No entanto, dependendo da sua cadeia de ferramentas, isso pode acontecer de qualquer maneira. Puramente da perspectiva do design, a consistência geralmente é uma coisa boa.

qid
fonte
1
A taxa na qual você precisa "se alternar" entre os contêineres STL e Qt em um aplicativo real que usa STL, exceto quando a interface com o Qt geralmente é superestimada. Na maioria das vezes, você faz std :: transform vindo de / para a camada de apresentação (que usa Qt) e obtém a opção de contêiner gratuitamente. As partes interessadas podem procurar em projects.kde.org/projects/kde/kdepim/repository/revisions/… para ver por si mesmas.
Marc Mutz - mmutz
8

Se os dados com os quais você está trabalhando são usados ​​principalmente para conduzir a interface do usuário baseada em Qt, use definitivamente recipientes Qt.

Se os dados são usados ​​principalmente internamente no aplicativo e é provável que você não se desloque para o Qt, então, salvo problemas de desempenho, use os contêineres do Qt, pois isso facilitará o processamento dos bits de dados que vão para a interface do usuário.

Se os dados forem usados ​​principalmente em conjunto com outras bibliotecas que conhecem apenas contêineres STL, use contêineres STL. Se você tiver essa situação, estará em apuros, não importa o que aconteça, porque você fará muitas mudanças entre os tipos de contêiner, não importa o que você faça.

Michael Kohne
fonte
7

Além da diferença de COW, os contêineres STL são muito mais suportados em uma variedade de plataformas. O Qt é portátil o suficiente se você limitar seu trabalho a plataformas "tradicionais", mas o STL também está disponível em muitas outras plataformas mais obscuras (por exemplo, os DSPs da Texas Instruments).

Como o STL é padrão e não controlado por uma única corporação, geralmente há mais programadores que podem ler, entender e modificar facilmente o código STL e mais recursos (livros, fóruns on-line, conferências, etc.) para apoiá-los. fazendo isso do que o Qt. Isso não quer dizer que se deva fugir do Qt apenas por esse motivo; apenas que, como todas as outras coisas são iguais, você deve usar o STL como padrão, mas é claro que todas as coisas raramente são iguais, então você terá que decidir em seu próprio contexto o que faz mais sentido.

Em relação à resposta da AlexKR: o desempenho do STL é garantido dentro de limites, mas uma determinada implementação pode fazer uso de detalhes dependentes da plataforma para acelerar seu STL. Portanto, nesse sentido, você pode obter resultados diferentes em plataformas diferentes, mas nunca será mais lento que a garantia explícita (erros de módulo).

metal
fonte
9
Com relação ao seu primeiro ponto: presumo que o OP esteja se referindo a projetos que já usam Qt e, portanto, já estejam limitados a plataformas "mainstream". Parece improvável que alguém extraia uma biblioteca tão pesada como o Qt apenas para suas classes de contêineres.
criar o seu alerta
4

Meus cinco centavos: os contêineres Qt devem funcionar de maneira semelhante em plataformas diferentes. Enquanto os contêineres STL dependem da implementação do STL. Você pode obter resultados de desempenho diferentes.

Edição: Eu não estou dizendo que STL é "mais lento", mas aponto para efeitos de vários detalhes de implementação.
Por favor, verifique isto , e então talvez isto .
E não é um problema real de STL. Obviamente, se você tiver uma diferença significativa no desempenho, haverá um problema no código que usa STL.

alexkr
fonte
Os contêineres STL são todos semelhantes, independentemente da implementação. Você não pode ter um vetor implementado como uma lista nos bastidores, pois ele deve estar em um bloco de memória contíguo. O STL também é geralmente otimizado para grandes extensões em todas as principais plataformas.
Yacoby 3/11/2009
1
Se você seguir o que o STL promete (em vez de assumir como é implementado), nunca terá problemas ao mover-se entre plataformas com o STL. Mesmo com Qt.
22630 Michael Kohne
Este é exatamente o oposto de verdadeiro. Os contêineres STL sempre funcionam da mesma maneira em todas as plataformas; se não, não são STL. O QT, no entanto, altera drasticamente o desempenho de versão para versão; portanto, em uma plataforma com QT4.0 em vez de QT4.8, é possível obter algumas alterações sérias.
Alice
1
Você está confundindo dois tipos muito diferentes de desempenho; desempenho algorítmico e desempenho computacional prático. Todas as implementações STL garantem o mesmo desempenho algorítmico; se o seu vetor leva um tempo de log (n) para indexar um elemento, não é um vetor STL. Seus links apontam para o desempenho computacional prático, que não faz sentido nesta discussão; O QT altera seus algoritmos entre as versões, e o mesmo C ++ em plataformas diferentes obtém desempenho diferente. Estes são, na minha experiência, muito mais maleáveis ​​do que as diferenças no desempenho da STL.
Alice
3

Eu acho que depende da maneira como você usa o Qt. Se você usá-lo em todo o produto, provavelmente faz sentido usar recipientes Qt. Se você o contiver apenas (por exemplo) na parte da interface do usuário, talvez seja melhor usar contêineres padrão C ++.

Nemanja Trifunovic
fonte
3

Sou da opinião de que o STL é um excelente software, no entanto, se devo fazer alguma programação relacionada ao KDE ou Qt, então o Qt é o caminho a seguir. Também depende do compilador que você está usando, pois o GCC STL funciona muito bem; no entanto, se você precisar usar o SUN Studio CC, o STL provavelmente causará dores de cabeça por causa do compilador e não do STL. Nesse caso, como o compilador fará sua cabeça doer, basta usar o Qt para evitar problemas. Apenas meus 2 centavos ...

Paulo Lopes
fonte
3

Há uma (às vezes) grande limitação no QVector. Ele só pode alocar int bytes de memória (observe que o limite está em bytes e não no número de elementos). Isso implica que tentar alocar blocos contíguos de memória maiores que ~ 2 GB com um QVector levará a uma falha. Isso acontece com o Qt 4 e 5. std :: vector não tem essa limitação.

fedemp
fonte
0

O principal motivo para usar contêineres STL para mim é se você precisar de um alocador personalizado para reutilizar a memória em contêineres muito grandes. Suponha, por exemplo, que você tenha um QMap que armazene 1000000 entradas (pares de chave / valor). No Qt, isso implica exatamente 1000000 milhões de alocações (new chamadas), não importa o quê. No STL, você sempre pode criar um alocador personalizado que aloca internamente toda a memória de uma só vez e atribui-a a cada entrada à medida que o mapa é preenchido.

Meu conselho é usar contêineres STL ao escrever algoritmos críticos de desempenho na lógica de negócios e convertê-los novamente em contêineres Qt quando os resultados estiverem prontos para serem exibidos pelos controles e formulários da interface do usuário, se necessário.

Darien Pardinas
fonte
Não tentando defender a QTL aqui, mas você pode especializar-se QMapNode<K,V>para o seu K, Vpara fornecer o seu próprio operator new.
precisa saber é o seguinte