Contenitori STL o Qt?


185

Quali sono i pro ei contro di utilizzare contenitori Qt ( QMap, QVector, ecc) sul loro STL equivalente?

Vedo un motivo per preferire Qt:

  • I contenitori Qt possono essere passati ad altre parti di Qt. Ad esempio, possono essere utilizzati per popolare a QVariante quindi a QSettings(con qualche limitazione, tuttavia, vengono accettati solo QListe QMap/ le QHashcui chiavi sono stringhe).

Ce n'è un altro?

Modifica : supponendo che l'applicazione si basi già su Qt.

Risposte:


135

Ho iniziato utilizzando std::(w)stringesclusivamente i contenitori STL e convertendoli in / dagli equivalenti Qt, ma sono già passato a QStringe trovo che utilizzo sempre più i contenitori Qt.

Quando si tratta di stringhe, QStringoffre funzionalità molto più complete rispetto a std::basic_stringed è completamente compatibile con Unicode. Offre anche un'efficace implementazione delle COW , su cui sono arrivato a fare molto affidamento.

I contenitori di Qt:

  • offre la stessa implementazione COW di in QString, che è estremamente utile quando si tratta di usare la foreachmacro di Qt (che fa una copia) e quando si usano meta-tipi o segnali e slot.
  • può usare iteratori in stile STL o iteratori in stile Java
  • sono streaming con QDataStream
  • sono ampiamente utilizzati nell'API di Qt
  • avere un'implementazione stabile su tutti i sistemi operativi. Un'implementazione STL deve obbedire allo standard C ++, ma per il resto è libera di fare ciò che gli pare (vedi la std::stringcontroversia sulle COW). Alcune implementazioni STL sono particolarmente dannose.
  • fornire hash, che non sono disponibili se non si utilizza TR1

La QTL ha una filosofia diversa dalla STL, che è ben riassunta da J. Blanchette: "Mentre i contenitori di STL sono ottimizzati per la velocità pura, le classi di contenitori di Qt sono state attentamente progettate per offrire praticità, utilizzo minimo della memoria ed espansione minima del codice".
Il link sopra fornisce ulteriori dettagli sull'implementazione del QTL e quali ottimizzazioni vengono utilizzate.


12
Nel nuovo standard c ++ 0x COW è praticamente fuori dal tavolo.

16
re: "progettato con cura per fornire [...] un utilizzo minimo della memoria". Non dovresti credere al marketing. Profilo QList<double>su un'architettura a 32 bit per l'utilizzo della memoria per vedere di persona.
Marc Mutz - mmutz,

11
"Offre anche un'implementazione efficiente di COW": COW non è poi così efficiente quando si tratta di applicazioni multithread ...
Grizzly,

5
@ MarcMutz-mmutz prova a profilare QVectorinvece di QList. Ci sono piuttosto spiegazioni su Qt, che QList è progettato per memorizzare i puntatori sugli oggetti. Pertanto, ogni elemento doppio creato dinamicamente e il puntatore a questo elemento viene archiviato QList. QList è progettato come contenitore "centrale" tra il vettore e l'elenco collegato. Non è progettato per casi critici di memoria / prestazioni.
Dmitry Sazonov,

2
@ user1095108 Non c'è niente di sbagliato in questo. Vai usa lo stl. Alcuni di noi preferiscono scrivere rapidamente il codice corretto. Non c'è niente di sbagliato in questo.
weberc2,

178

Questa è una domanda a cui è difficile rispondere. Può davvero ridursi a una discussione filosofica / soggettiva.

Detto ciò...

Consiglio la regola "Quando a Roma ... fai come fanno i romani"

Ciò significa che se sei nella terra di Qt, codifica come fanno i Qt'ians. Questo non è solo per problemi di leggibilità / coerenza. Considera cosa succede se memorizzi tutto in un contenitore stl, quindi devi passare tutti quei dati a una funzione Qt. Vuoi davvero gestire un sacco di codice che copia le cose dentro / fuori dai contenitori Qt. Il tuo codice è già fortemente dipendente da Qt, quindi non è come se lo rendessi più "standard" usando i contenitori stl. E qual è il punto di un contenitore se ogni volta che vuoi usarlo per qualcosa di utile, devi copiarlo nel corrispondente contenitore Qt?


1
+1 hai perfettamente ragione, è quello che ho cercato di spiegare nella mia domanda ("Riesco a vedere un motivo per preferire Qt"), quindi l'ho modificato leggermente. Grazie
Julien-L

Assolutamente ben detto. Se stai facendo QT, usa le cose QT! Immagina il momento "WTF" per il manutentore quando apre un'applicazione QT e vede QT e STL usati in modo intercambiabile. Ciò potrebbe finire per essere un incubo (non necessario).
È

5
@ It'sPete STL fa parte dello standard; QT non lo è. Qualsiasi codice che utilizza lo standard non dovrebbe mai innescare un momento "WTF".
Alice,

6
I romani misero i loro prigionieri nel Colosseo e poi li cacciarono con i leoni. Se conosci meglio, non seguire le abitudini locali. Questo è vero in Qt come sarebbe stato per Modern Man nell'Impero Romano ...
Marc Mutz - mmutz

1
@mmutz dici che è una brutta cosa, vorrei mettere un po 'di codice che ho trovato in quel Colosseo e guardare lo spettacolo
slf

65

I contenitori Qt sono più limitati di quelli STL. Alcuni esempi di dove quelli STL sono superiori (tutti questi che ho colpito in passato):

  • STL è standardizzato, non cambia con ogni versione di Qt (Qt 2 aveva QList(basato sul puntatore) e QValueList(basato sul valore); Qt 3 aveva QPtrListe QValueList; Qt 4 ora ha QList, e non è affatto come QPtrList o QValueList ).
    Anche se finisci per usare i contenitori Qt, usa il sottoinsieme API compatibile con STL (cioè push_back(), no append(); front()no)first() , ...) per evitare porting ancora una volta venire Qt 5. In entrambi Qt2-> 3 e Qt3-> 4 transizioni, i cambiamenti nei contenitori Qt erano tra quelli che richiedevano la maggior quantità di abbandono del codice.
  • Tutti i contenitori bidirezionali STL hanno rbegin() / rend(), rendendo l'iterazione inversa simmetrica rispetto all'iterazione in avanti. Non tutti i contenitori Qt li hanno (quelli associativi no), quindi l'iterazione inversa è inutilmente complicata.
  • I contenitori STL possono insert()variare da diversi tipi di iteratori, ma compatibilistd::copy() molto meno necessario.
  • I contenitori STL hanno un Allocatorargomento template, rendendo la gestione della memoria personalizzata banale (typedef richiesto), rispetto a Qt (fork di QLineEditrichiesto per s/QString/secqstring/). EDIT 20171220 : questo interrompe Qt dei progressi nella progettazione degli allocatori a seguito di C ++ 11 e C ++ 17, cfr. ad esempio il discorso di John Lakos ( parte 2 ).
  • Non esiste un Qt equivalente a std::deque.
  • std::listha splice(). Ogni volta che mi trovo a usare std::list, è perché ne ho bisogno splice().
  • std::stack, std::queueAggregare adeguatamente la loro sottostante contenitore, e non ereditano, come QStack, QQueuefare.
  • QSetè come std::unordered_set, non come std::set.
  • QListè semplicemente strano .

Molti di questi argomenti potrebbero essere risolti abbastanza facilmente in Qt , ma al momento la libreria di container in Qt sembra sperimentare una mancanza di attenzione allo sviluppo.

EDIT 20150106 : Dopo aver trascorso un po 'di tempo a provare a fornire il supporto C ++ 11 alle classi container Qt 5, ho deciso che non valeva il lavoro. Se osservi il lavoro che viene messo nelle implementazioni della libreria standard C ++, è abbastanza chiaro che le classi Qt non raggiungeranno mai. Abbiamo rilasciato Qt 5.4 ora eQVector ancora non sposta elementi sulle riallocazioni, non haemplace_back()o valore-push_back()... Di recente abbiamo anche rifiutato unQOptionalmodello di classe, aspettandostd::optionalinvece. Allo stesso modo perstd::unique_ptr. Spero che questa tendenza continui.


3
Huh. Avevo l'impressione che QList fosse l'equivalente di std::deque. Chiaramente, non avrei dovuto semplicemente sfogliare la documentazione.
Dennis Zickefoose,

QVectorha avuto crbegine amici da Qt 5.6
Bart Louwers il

@Alex: giusto, ho aggiunto quelli facili, ma non tutti i contenitori Qt li hanno ancora (perché non li usi std::reverse_iteratorsopra i file rotti QHash/ QMapiteratori, che, se non referenziati, ritornano mapped_typeinvece di value_type). Niente che non possa essere risolto, ma vedi il mio EDIT dal 2015.
Marc Mutz - mmutz

@ MarcMutz-mmutz Grazie per il chiarimento.
Bart Louwers,

Può valere la pena aggiungere all'elenco il fatto che ad esempio QVectorutilizza intcome indice, limitando così le dimensioni a 31 bit (anche su sistemi a 64 bit). Inoltre, non può nemmeno memorizzare INT_MAXelementi di dimensioni superiori a 1 byte. Ad esempio, il più grande .size()che potrei avere QVector<float>su Linux gcc x86_64 era 536870907 elementi (2²⁹-5), mentre std::vector<float>allocato con successo 4294967295 elementi (2³²-1; non ho provato di più a causa della mancanza di RAM per questo (questa dimensione richiede già 16 GiB) ).
Ruslan,

31

Analizziamo queste affermazioni in fenomeni misurabili reali:

  • Più leggero: i contenitori Qt utilizzano meno memoria dei contenitori STL
  • Più sicuro: i contenitori Qt hanno meno opportunità di essere utilizzati in modo improprio
  • Più facile: i contenitori Qt presentano meno di un carico intellettuale

Più facile

L'affermazione fatta in questo contesto è che l'iterazione in stile java è in qualche modo "più semplice" rispetto allo stile STL, e quindi Qt è più facile da usare grazie a questa interfaccia aggiuntiva.

Stile Java:

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

Stile STL:

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

Lo stile iteratore Java ha il vantaggio di essere un po 'più piccolo e più pulito. Il problema è che questo non è più lo stile STL.

Stile C ++ 11 STL

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

o

C ++ 11 foreach style

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

Che è così drasticamente semplice che non c'è motivo di usare altro (a meno che non si supporti C ++ 11).

Il mio preferito, tuttavia, è:

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

Quindi, come possiamo vedere, questa interfaccia non ci guadagna nulla se non un'interfaccia aggiuntiva, in aggiunta a un'interfaccia già elegante, snella e moderna. Aggiunta di un livello di astrazione non necessario oltre a un'interfaccia già stabile e utilizzabile? Non è la mia idea di "più facile".

Inoltre, le interfacce Qt foreach e java aggiungono sovraccarico; copiano la struttura e forniscono un livello non necessario di indiretta. Questo potrebbe non sembrare molto, ma perché aggiungere un livello di sovraccarico per fornire un'interfaccia non molto più semplice? Java ha questa interfaccia perché java non ha un sovraccarico dell'operatore; C ++ lo fa.

Safer

La giustificazione fornita da Qt è il problema della condivisione implicita, che non è né implicito né un problema. Implica tuttavia la condivisione.

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

Innanzitutto, questo non è implicito; stai assegnando esplicitamente un vettore a un altro. Le specifiche dell'iteratore STL indicano chiaramente che gli iteratori appartengono al contenitore, quindi abbiamo chiaramente introdotto un contenitore condiviso tra b e a. Secondo, questo non è un problema; fintanto che verranno seguite tutte le regole delle specifiche dell'iteratore, nulla andrà per il verso sbagliato. L'unica volta che qualcosa va storto è qui:

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

Qt lo specifica come se significasse qualcosa, come un problema sorge de novo da questo scenario. Non L'iteratore è invalidato e, proprio come tutto ciò a cui è possibile accedere da più aree disgiunte, è così che funziona. In effetti, ciò accadrà facilmente con gli iteratori in stile Java in Qt, grazie alla sua forte dipendenza dalla condivisione implicita, che è un antipattern come documentato qui e in molte altre aree . Sembra particolarmente strano che questa "ottimizzazione" venga messa in atto in un framework sempre più orientato al multithreading, ma questo è marketing per te.

Accendino

Questo è un po 'più complicato. L'uso delle strategie di condivisione e crescita implicite di copia e scrittura rende molto difficile fornire effettivamente garanzie sulla quantità di memoria che il contenitore utilizzerà in un determinato momento. Questo è diverso dall'STL, che offre forti garanzie algoritmiche.

Sappiamo che il limite minimo di spazio sprecato per un vettore è la radice quadrata della lunghezza del vettore , ma sembra che non ci sia modo di implementarlo in Qt; le varie "ottimizzazioni" che supportano impedirebbero questa importantissima funzione di risparmio di spazio. L'STL non richiede questa funzionalità (e la maggior parte utilizza una crescita raddoppiata, che è più dispendiosa), ma è importante notare che potresti almeno implementare questa funzionalità, se necessario.

Lo stesso vale per gli elenchi doppiamente collegati, che potrebbero utilizzare il collegamento XOr per ridurre drasticamente lo spazio utilizzato. Ancora una volta, questo è impossibile con Qt, a causa dei suoi requisiti di crescita e COW.

Le COW possono davvero rendere qualcosa di più leggero, ma anche i contenitori intrusivi, come supportati da boost , e Qt li usavano frequentemente nelle versioni precedenti, ma non vengono più utilizzati tanto perché sono difficili da usare, non sicuri e impongono un onere sul programmatore. COW è una soluzione molto meno invadente, ma poco attraente per le ragioni sopra esposte.

Non vi è alcun motivo per cui non è possibile utilizzare contenitori STL con lo stesso costo di memoria o meno dei contenitori di Qt, con l'ulteriore vantaggio di sapere effettivamente quanta memoria si sprecherà in un determinato momento. Sfortunatamente, è impossibile confrontare i due nell'uso della memoria non elaborata, poiché tali benchmark mostrerebbero risultati incredibilmente diversi in diversi casi d'uso, che è esattamente il tipo di problema che l'STL è stato progettato per correggere.

In conclusione

Evita l'uso dei contenitori Qt quando possibile, senza imporre un costo di copia, e usa l'iterazione del tipo STL (forse attraverso un wrapper o la nuova sintassi), quando possibile.


4
I tuoi punti sono in gran parte validi, ma ci sono alcune informazioni fuorvianti: Adding an unnecessary level of abstraction on top of an already stable and usable interface? Not my idea of "easier".gli iteratori in stile Java di Qt non sono stati aggiunti su C ++ 11; lo precedono. Comunque Qt foreach(QString elem, list)è facile come foreach di C ++ 11 o BOOST_FOREACH e funziona con compilatori conformi a pre-C ++ 11.
weberc2,

@ weberc2 Sei confuso; Gli iteratori in stile Java di Qt vengono aggiunti agli iteratori C ++ (non C ++ 11). È un ulteriore livello di astrazione (e uno inutile) che gonfia l'interfaccia, il che non è più facile. E foreach per Qt non è facile come BOOST_FOREACH, in quanto non è altrettanto sicuro e non ha la stessa ampiezza di supporto (BOOST_FOREACH può applicarsi a qualsiasi intervallo, per qualsiasi versione di C ++, dove come foreach in QT richiede C + +03 conformità). La ricerca di QT dovrebbe essere evitata a tutti i costi.
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".(enfasi mia) L'hai detto subito dopo che ci hai mostrato le versioni C ++ 11 e BOOST di foreach, facendo sembrare che la versione Qt sia costruita su uno di quei due, il che non è il caso AFAICT. Sono sicuro che non è quello che volevi dire, ma è così che viene fuori. Da qui "informazioni fuorvianti".
weberc2,

It's an additional layer of abstraction (and an unnecessary one) that bloats the interface, which is not easier.Non è ancora chiaro con cosa stai confrontando. Iteratori C ++ 03? Iteratori C ++ 11? BOOST_FOREACH? Tutti i precedenti?
weberc2,

1
Sto solo dicendo che spesso sei molto ambiguo riguardo al metodo di iterazione a cui ti riferisci. Credo che pensi di essere chiaro e che la tua lingua sia ragionevole, ma sembra strano rifiutare di specificare. Accetto di non essere d'accordo, suppongo.
weberc2,

23

Contenitori STL:

  • Avere garanzie di prestazione
  • Può essere utilizzato negli algoritmi STL che hanno anche garanzie di prestazioni
  • Può essere sfruttato da librerie C ++ di terze parti come Boost
  • Sono standard e probabilmente sopravvivranno a soluzioni proprietarie
  • Incoraggiare la programmazione generica di algoritmi e strutture di dati. Se si scrivono nuovi algoritmi e strutture di dati conformi a STL, è possibile sfruttare ciò che STL fornisce già gratuitamente.

5
Tutto quanto sopra tranne essere uno standard vale anche per QTL, a condizione che si compili Qt con il supporto STL (impostazione predefinita). Il supporto STL include funzioni iteratore, typedef del contenitore (const_iterator, ecc.), Funzioni di conversione (da / verso STL).
rpg,

2
Qt non è proprietario
txwikinger

3
@rpg Quasi tutti non sono veri per QTL; QTL non ha garanzie di prestazioni elevate (come le hanno prontamente infrante in passato), non sono conformi a STL (nessun reverse, e quindi non possono essere utilizzate da molti boost), non sono standard (cambiano costantemente tra le versioni), e lo fanno non incoraggiare la programmazione generica (non hanno argomenti modello per gli allocatori, per esempio).
Alice,

15

I contenitori Qt usano un linguaggio copia-scrittura.


2
+1, potrebbe essere un vantaggio significativo in termini di prestazioni e risorse
RedGlyph

32
O potrebbe essere uno svantaggio significativo. Vedi gotw.ca/publications/optimizations.htm
Kaz Dragon,

3
Il conto atomico sembra andare abbastanza bene: labs.trolltech.com/blogs/2006/10/16/…
rpg

I contenitori STL sono liberi di usare qualsiasi linguaggio esistente purché soddisfino le loro garanzie di prestazione e le specifiche. COW è valido, anche con C ++ 11 / C ++ 14 STL.
Alice,

1
@Alice COW non è un'implementazione valida per la maggior parte del tempo perché rompe la complessità dello standard e garantisce la validità dell'iteratore in quasi ogni caso. Una delle poche classi che potevano essere implementate con COW era std::basic_stringe lo standard ha intrapreso azioni con C ++ 11 per renderlo non conforme.
Tiago Gomes,

9

Uno dei problemi principali è che l'API di Qt si aspetta che tu fornisca dati nei contenitori di Qt, quindi puoi anche semplicemente usare i contenitori di Qt piuttosto che trasformarti avanti e indietro tra i due.

Inoltre, se stai già utilizzando i contenitori Qt, potrebbe essere leggermente più ottimale usarli esclusivamente, poiché non dovresti includere i file di intestazione STL e potenzialmente collegarti nelle librerie STL. Tuttavia, a seconda della tua toolchain, ciò può accadere comunque. Solo dal punto di vista del design, la coerenza è generalmente una buona cosa.


1
La velocità con cui è necessario "trasformare avanti e indietro" tra i contenitori STL e Qt in un'applicazione reale che utilizza STL, tranne nei casi in cui l'interfaccia con Qt è generalmente ampiamente sopravvalutata. La maggior parte delle volte fai un po 'di std :: transform proveniente da / dal livello di presentazione (che usa Qt) e ottieni lo switch contenitore gratuitamente. Le parti interessate possono consultare il sito projects.kde.org/projects/kde/kdepim/repository/revisions/… per vedere di persona.
Marc Mutz - mmutz,

8

Se i dati con cui stai lavorando vengono utilizzati principalmente per guidare l'interfaccia utente basata su Qt, utilizza sicuramente i contenitori Qt.

Se i dati vengono principalmente utilizzati internamente nell'app e non è probabile che tu porti via Qt, quindi escludendo i problemi di prestazioni, usa i contenitori Qt perché renderà più facili da gestire i bit di dati che vanno all'interfaccia utente.

Se i dati vengono utilizzati principalmente in combinazione con altre librerie che conoscono solo i contenitori STL, utilizzare i contenitori STL. Se hai questa situazione, sei nei guai, qualunque cosa accada, perché eseguirai molto il porting avanti e indietro tra i tipi di container, qualunque cosa tu faccia.


7

Oltre alla differenza COW, i contenitori STL sono molto più ampiamente supportati su una varietà di piattaforme. Qt è abbastanza portatile se si limita il proprio lavoro alle piattaforme "mainstream", ma l'STL è disponibile anche su molte altre piattaforme più oscure (ad esempio, i DSP di Texas Instruments).

Poiché lo STL è standard anziché controllato da una singola società, ci sono, in generale, più programmatori che possono facilmente leggere, comprendere e modificare il codice STL e più risorse (libri, forum online, conferenze, ecc.) Per supportarli in facendo questo che ci sono per Qt. Questo non vuol dire che si dovrebbe rifuggire da Qt solo per questo motivo; solo che, a parità di tutte le altre cose, dovresti impostare di default l'STL, ma ovviamente tutte le cose raramente sono uguali, quindi dovrai decidere nel tuo contesto quale ha più senso.

Per quanto riguarda la risposta di AlexKR: le prestazioni STL sono garantite entro certi limiti, ma una determinata implementazione può fare uso di dettagli dipendenti dalla piattaforma per accelerare il loro STL. Quindi, in tal senso, potresti ottenere risultati diversi su piattaforme diverse, ma non sarà mai più lento della garanzia esplicita (bug del modulo).


9
Per quanto riguarda il tuo primo punto: presumo che il PO si riferisca a progetti che già utilizzano Qt e che pertanto sono già limitati alle piattaforme "mainstream". Sembra improbabile che qualcuno entri in una libreria così pesante come Qt solo per le sue classi di container.
ThisSuitIsBlackNon

4

I miei cinque centesimi: i contenitori Qt dovrebbero funzionare in modo simile su piattaforme diverse. Mentre i contenitori STL dipendono dall'implementazione STL. Potresti ottenere risultati di prestazione diversi.

EDIT: non sto dicendo che STL è "più lento", ma indico gli effetti di vari dettagli di implementazione.
Per favore, controlla questo e poi forse questo .
E non è un vero problema di STL. Ovviamente, se si ha una differenza significativa nelle prestazioni, allora c'è un problema nel codice che utilizza STL.


I contenitori STL sono tutti simili, indipendentemente dall'implementazione. Non è possibile implementare un vettore come un elenco dietro le quinte in quanto deve trovarsi in un blocco contiguo di memoria. L'STL è inoltre generalmente ottimizzato in misura considerevole su tutte le principali piattaforme.
Yacoby,

1
Se ti attieni a ciò che promette la STL (invece di supporre come sia implementata) non avrai mai problemi a spostarti tra le piattaforme con STL. Lo stesso con Qt.
Michael Kohne,

Questo è l'esatto contrario di vero. I contenitori STL funzionano sempre allo stesso modo su tutte le piattaforme; se non lo fanno, non sono STL. QT, tuttavia, modifica drasticamente le prestazioni da una versione all'altra, quindi su una piattaforma con QT4.0 anziché QT4.8, è possibile ottenere alcune serie modifiche.
Alice,

1
Stai confondendo due tipi molto diversi di performance; prestazione algoritmica e prestazione computazionale pratica. Tutte le implementazioni STL garantiscono le stesse prestazioni algoritmiche; se il tuo vettore impiega il tempo di log (n) per indicizzare un elemento, non è un vettore STL. I tuoi collegamenti rimandano a prestazioni computazionali pratiche, che non hanno senso in questa discussione; QT modifica i loro algoritmi tra le versioni e lo stesso C ++ su piattaforme diverse ottiene prestazioni diverse. Questi sono, nella mia esperienza, molto più malleabili delle differenze nelle prestazioni STL.
Alice,

3

Immagino che dipenda dal modo in cui usi Qt. Se lo usi su tutto il tuo prodotto, probabilmente ha senso usare i contenitori Qt. Se lo si contiene solo (ad esempio) nella parte dell'interfaccia utente, potrebbe essere preferibile utilizzare contenitori standard C ++.


3

Sono dell'opinione che STL sia un eccellente software, tuttavia se devo fare un po 'di programmazione relativa a KDE o Qt, Qt è la strada da percorrere. Inoltre dipende dal compilatore che stai utilizzando, con GCC STL funziona abbastanza bene, tuttavia se devi usare diciamo SUN Studio CC, molto probabilmente STL ti causerà mal di testa a causa del compilatore e non dell'STL in sé. In quel caso, dal momento che il compilatore ti farà male alla testa, basta usare Qt per salvarti il ​​disturbo. Solo i miei 2 centesimi ...


3

C'è una (a volte) grande limitazione in QVector. Può allocare solo byte int di memoria (si noti che il limite è in byte e non in numero di elementi). Ciò implica che il tentativo di allocare blocchi di memoria contigui di dimensioni superiori a ~ 2 GB con un QVector porterà a un arresto anomalo. Questo succede con Qt 4 e 5. std :: vector non ha questa limitazione.


0

Il motivo principale per utilizzare i contenitori STL per me è se è necessario un allocatore personalizzato per riutilizzare la memoria in contenitori molto grandi. Supponiamo ad esempio di avere una QMap che memorizza 1000000 voci (coppie chiave / valore). In Qt ciò implica esattamente 1000000 milioni di allocazioni (new chiamate), non importa quale. In STL è sempre possibile creare un allocatore personalizzato che alloca internamente tutta quella memoria in una sola volta e assegnarla a ciascuna voce quando viene popolata la mappa.

Il mio consiglio è di utilizzare i contenitori STL durante la scrittura di algoritmi critici per le prestazioni nella logica aziendale e di convertirli nuovamente in contenitori Qt quando i risultati sono pronti per essere visualizzati dai controlli e dai moduli dell'interfaccia utente, se necessario.


Non cercare di difendere il QTL qui, ma si potrebbe specializzarsi QMapNode<K,V>per il vostro K, Vper fornire il proprio operator new.
Marc Mutz - mmutz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.