2015-05-14 10 views
5

Sono stato troppo pensieroso (alcuni potrebbero dire underthinking, vediamo cosa succede) la costanza dei contenitori STL e dei loro elementi.Costellazione dei contenitori STL e dei loro elementi - quando utilizzare const?

Ho cercato una discussione su questo, ma i risultati sono stati sorprendentemente scarsi. Quindi non sono necessariamente alla ricerca di una risposta definitiva, sarei altrettanto contento di una discussione che fa muovere di nuovo gli ingranaggi nella mia testa.

Diciamo che ho una classe che mantiene std :: stringhe in un vettore std ::. La mia classe è un dizionario che legge le parole da un file di dizionario. Non saranno mai cambiati. Così sembra prudente dichiareremo come

std::vector<const std::string> m_myStrings; 

Tuttavia, ho letto i commenti sparsi che non si deve utilizzare gli elementi in un const std :: vector, in quanto gli elementi devono essere assegnabili.

Domanda:

  • ci sono casi in cui gli elementi sono utilizzati in const std :: vector (esclusi hack, ecc)?

  • Gli elementi const sono utilizzati in altri contenitori? Se sì, quali, e quando?

Sto principalmente parlando di tipi di valore come elementi qui, non puntatori.

risposta

2

No, per la ragione in cui affermi.

+0

Ok, un semplice no è sufficiente - almeno significa che ho capito bene. EDIT: Vorrei davvero che il compilatore potesse cogliere questo utilizzo. Mi rendo conto che ci sono ragioni per non farlo, però. – Leander

+0

@Leander: Ok, un semplice "Ok" è sufficiente. –

-1

considerano utilizzando

std::vector<std::shared_ptr<const std::string>> 

invece?

+0

Grazie per il suggerimento, ma sto cercando di evitare i puntatori qui, anche quelli intelligenti. :) – Leander

+0

_ "Sto principalmente parlando di tipi di valore come elementi qui, non di puntatori." _ –

+0

In ogni caso, questo non risponde alla domanda. – juanchopanza

2

Nel contesto di std::vector, non credo ha senso utilizzare un qualificatore const con il suo parametro di modello, perché un std::vector è per sua natura dinamica e può essere richiesto di "muoversi" in memoria al fine di "ridimensionare "stesso.

Nello standard C++ 03, std::vector è archiviato in memoria contigua. Questo richiede quasi che std::vector sia implementato con una qualche forma di array. Ma come possiamo creare un array dinamico che modifica le dimensioni? Non possiamo semplicemente "aggiungere" memoria alla fine di esso - che richiederebbe un nodo aggiuntivo (e una lista collegata) o fisicamente mettendo le nostre voci aggiuntive alla fine dell'array, che sarebbe o fuori dalla limiti o ci richiedono di riservare più memoria in primo luogo.

Quindi, suppongo che std::vector abbia bisogno di allocare un array addizionale, copiare o spostare i suoi membri nell'array finale e quindi eliminare quello vecchio.

Non è garantito che una mossa o copiare l'assegnazione per ogni oggetto su modelli in grado di std::vector sarebbe non cambiamento dell'oggetto sottostante viene spostato o copiato - è considerato una buona forma per fare aggiungere il qualificatore const, ma non è richiesto Pertanto, non possiamo consentire un std::vector<const T>.

correlati: How is C++ std::vector implemented?

4

La mia classe è un dizionario che legge le parole da un file dizionario. Non saranno mai cambiati.

L'incapsulamento può essere d'aiuto.

Chiedi alla tua classe di tenere un vector<string>, ma rendilo privato. Quindi aggiungi un accessor alla tua classe che restituisce un const vector<string> & e fallo passare ai chiamanti.

I chiamanti non possono modificare il vettore e operator [] sul vettore li consegnerà const string &, che è esattamente ciò che si desidera.

+0

Questo è un buon suggerimento ed è praticamente quello che ho deciso di fare. Poiché la tua soluzione richiede di fare una copia dell'intero vettore, probabilmente fornirò un'interfaccia simile a questa: 'void iterateWords (std :: function func);': quindi i chiamanti può fornire una funzione lambda per fare quello che vogliono con le stringhe. – Leander

Problemi correlati