vectors - vector c++




Per STL o! STL, questa è la domanda (10)

Ho iniziato a programmare C nel 1984 circa e non ho mai usato l'STL. Nel corso degli anni ho implementato le mie librerie di funzioni e si sono evolute e sviluppate quando STL non era ancora stabile e mancava il supporto multipiattaforma. La mia libreria comune è cresciuta fino ad includere il codice da altri (principalmente cose come libjpeg, libpng, ffmpeg, mysql) e pochi altri e preferisco mantenere la quantità di codice esterno al suo interno al minimo. Sono sicuro che ora l'STL è fantastico, ma sinceramente sono contento degli articoli nella mia cassetta degli attrezzi e non vedo alcuna necessità a questo punto di caricarlo con più strumenti. Ma certamente vedo i grandi passi avanti che i nuovi programmatori possono fare usando l'STL senza dover codificare tutto da zero.

Indubbiamente, sceglierei di usare l'STL per la maggior parte dei progetti di programmazione C ++. La domanda mi è stata presentata di recente, tuttavia, "Ci sono dei casi in cui non useresti l'STL?" ...

Più ci pensavo, più mi rendevo conto che forse DOVREBBE essere casi in cui scelgo di non usare l'STL ... Per esempio, un progetto molto lungo ea lungo termine il cui codebase dovrebbe durare anni ... Forse un la soluzione di container personalizzata che si adatta perfettamente alle esigenze dei progetti vale il sovraccarico iniziale? Cosa ne pensi, ci sono dei casi in cui sceglieresti NON in STL?


I progetti con requisiti di memoria rigidi come quelli per i sistemi incorporati potrebbero non essere adatti per l'STL, in quanto può essere difficile controllare e gestire ciò che viene prelevato e restituito all'heap. Come accennato Evan, la scrittura di allocatori appropriati può essere d'aiuto, ma se si contano tutti i byte utilizzati o interessati alla frammentazione della memoria, potrebbe essere più saggio realizzare una soluzione su misura per il proprio problema specifico, dal momento che l'STL è stato ottimizzato per l'uso più generale.

Si può anche scegliere di non usare STL per un caso particolare perché esistono più contenitori applicabili che non sono nello standard corrente, come boost :: array o boost :: unordered_map.


Di solito, trovo che la cosa migliore da fare sia usare lo STL con gli allocatori personalizzati invece di sostituire i contenitori STL con quelli arrotolati a mano. La cosa bella dell'STL è che paghi solo per quello che usi.


Ho riscontrato problemi nell'utilizzo di STL nel codice multi-thread. Anche se non condividete gli oggetti STL attraverso i thread, molte implementazioni utilizzano costrutti non thread-safe (come ++ per il conteggio dei riferimenti invece di uno stile di incremento interbloccato o con allocatori non thread-safe).

In ognuno di questi casi, ho comunque deciso di utilizzare STL e correggere i problemi (ci sono abbastanza ganci per ottenere quello che vuoi).

Anche se si sceglie di creare le proprie raccolte, sarebbe una buona idea seguire lo stile STL per gli iteratori in modo da poter utilizzare algoritmi e altre funzioni STL che funzionano solo su iteratori.


Il problema principale che ho visto è dover integrare con il codice legacy che si basa sull'operatore di non lancio nuovo.


La maggior parte dei progetti su cui ho lavorato aveva una base di codice più vecchia di qualsiasi versione realmente utilizzabile di STL - quindi abbiamo scelto di non presentarla ora.


Penso che sia un tipico scenario di build vs buy. Tuttavia, penso che in questo caso vorrei quasi sempre "comprare", e usare STL - o una soluzione migliore (forse qualcosa da Boost), prima di lanciare il mio. Dovresti concentrare la maggior parte del tuo sforzo su ciò che fa l'applicazione, non sui blocchi che utilizza.


Una situazione in cui ciò potrebbe verificarsi è quando si sta già utilizzando una libreria esterna che già fornisce le capacità necessarie dall'STL. Ad esempio, la mia azienda sviluppa un'applicazione in aree con spazio limitato e utilizza già Qt per il toolkit per finestre. Dal momento che Qt fornisce classi di container simili a STL, usiamo quelle invece di aggiungere l'STL al nostro progetto.


Standard C ++ perversamente consente implementazioni di alcune operazioni di iteratore per generare eccezioni . Questa possibilità può essere problematica in alcuni casi. È quindi possibile implementare il proprio contenitore semplice che garantisce di non generare eccezioni per operazioni critiche.


Introduzione:

STL è una grande libreria e utile in molti casi, ma in definitiva non risolve tutte le situazioni. Rispondere a STL o! STL è come rispondere "STL soddisfa le tue necessità o no?"

Pro di STL

  • Nella maggior parte dei casi, STL ha un contenitore adatto per una determinata soluzione.
  • È ben documentato
  • È ben noto (i programmatori di solito lo sanno già, entrare in un progetto è più breve)
  • È testato e stabile.
  • È multipiattaforma
  • È incluso in ogni compilatore (non aggiunge una terza dipendenza dalla libreria)
  • STL è già implementato e pronto
  • STL è lucido, ...

Contras of STL

Non è necessario avere un semplice grafico, un albero rosso-nero o un database di elementi molto complesso con un AI che gestisce l'accesso simultaneo attraverso un computer quantico. Il fatto è che STL no e non risolverà mai tutto.

Gli aspetti seguenti sono solo alcuni esempi, ma in pratica sono la conseguenza di questo fatto: STL è una vera libreria con limiti.

  • Eccezioni: relè STL su eccezioni, quindi se per qualsiasi motivo non è possibile accettare eccezioni (ad es. Sicurezza critica), non è possibile utilizzare STL. Destra! le eccezioni possono essere disabilitate, ma ciò non risolve il progetto di inoltro STL su di esse e finirà per causare un arresto anomalo.

  • Necessità di una struttura dati specifica (non ancora inclusa): grafico, albero, ecc.

  • Vincoli speciali di complessità: è possibile scoprire che il contenitore generico di STL non è il più ottimale per il codice del collo di bottiglia.

  • Considerazioni sulla concorrenza: O è necessaria la concorrenza e STL non fornisce ciò che è necessario (ad esempio, il blocco lettore-scrittore non può (facilmente) essere utilizzato a causa dell'operatore bidirezionale [] operator ). O potresti progettare un contenitore sfruttando il multi-threading per un accesso / ricerca / inserimento / qualsiasi cosa molto più veloce.

  • STL deve adattarsi alle tue esigenze, ma il contrario è anche vero: devi soddisfare i bisogni di STL. Non provare a utilizzare std::vector in un microcontroller incorporato con 1K di RAM non gestita.

  • Compatibilità con altre librerie: può essere che per ragioni storiche, le librerie che usi non accettano STL (ad es. QtWidgets usa intensamente il proprio QList). La conversione di contenitori in entrambe le direzioni potrebbe non essere la soluzione migliore.

Implementare il proprio contenitore

Dopo averlo letto, potresti pensare: " Beh, sono sicuro che potrei fare qualcosa di meglio per il mio caso specifico di quello di STL. " ASPETTA!

Implementare correttamente il tuo contenitore diventa molto rapidamente un compito enorme: non si tratta solo di implementare qualcosa che funziona, potresti dover:

  • Documentalo profondamente, includendo limitazioni, complessità dell'algoritmo, ecc.
  • Aspettatevi bug e risolvendoli
  • Requisiti aggiuntivi in ​​entrata: sai, questa funzione è mancante, questa conversione tra tipi, ecc.
  • Dopo un po 'potresti volere refactoring e cambiare tutte le dipendenze (troppo tardi?)
  • ....

Il codice usato nel profondo del codice come un contenitore è definitivamente qualcosa che richiede tempo per essere implementato e dovrebbe essere attentamente.

Utilizzando la libreria di terze parti

Non STL non significa necessariamente personalizzato. Ci sono molte buone librerie in rete, alcune anche con licenza open source permissiva.

Aggiungere o meno un'ulteriore libreria di terze parti è un altro argomento, ma vale la pena di essere considerato.





containers