2015-10-14 10 views
20

So che in C++ 98, né std::basic_string<>std::vector<> sono stati richiesti per l'utilizzo dello spazio di archiviazione contiguo. Questo è stato visto come una svista per std::vector<> non appena è stato segnalato e, se non ricordo male, è stato corretto con C++ 03.std :: string ha bisogno di memorizzare il suo carattere in un pezzo di memoria contigua?

mi sembra di ricordare dopo aver letto su discussioni che richiedono std::basic_string<> di utilizzare memorizzazione contiguo indietro quando C++ 11 era ancora chiamato C++ 0x, ma non ho seguito la discussione a stretto contatto di allora, e sto ancora limitato al C++ 03 al lavoro, quindi non sono sicuro di cosa ne sia stato.

Quindi è necessario std::basic_string<> per l'archiviazione contigua? (Se è così, quale versione dello standard richiesto per primo?)

Nel caso in cui ti chiedi: Questo è importante se si dispone di codice passando il risultato di &str[0] a una funzione in attesa di un pezzo di memoria contiguo di scrivere. (So ​​di str.data(), ma per ovvie ragioni il vecchio codice non lo usa.)

+0

Bene, dato che 'str.data()' deve essere un tempo costante ed è necessario per restituire un blocco di memoria continua, concluderei che sì. –

+1

Vedi domande simili http://stackoverflow.com/questions/1986966/does-s0-point-to-contiguous-characters-in-a-stdstring e http://stackoverflow.com/questions/2256160/is-it- ragionevole-da-usare-stdbasic-stringt-as-a-contiguous-buffer-when-targeti, che risponde alla domanda ma in un modo che non è banale da leggere. – slaphappy

+0

Quali sono questi ovvi motivi per non usare 'data()'? Quella funzione era presente anche in C++ 03. – Angew

risposta

24

Il C++11 standard, basic_string 21.4.1.5,

Gli oggetti char-come in un oggetto basic_string devono essere conservati in modo contiguo. Cioè, per qualsiasi oggetto basic_string s, l'identità & * (s.begin() + n) == & * s.begin() + n deve valere per tutti i valori di n tale che 0 < = n < s .dimensione().

2

Secondo il progetto di norma N452721,4/3 modello Classe basic_string [basic.string]:

Una basic_string è un contenitore contigua (23.2.1).

13

In C++ 03 non era garantito che gli elementi della stringa siano memorizzati in modo continuo. [Basic.string] era

  1. Per un tipo di grafico char-simile, il modello di classe basic_string descrive oggetti che possono memorizzare una sequenza costituito da un numero variabile di oggetti arbitrari char-simile (clausola 21). Il primo elemento della sequenza è in posizione zero. Tale sequenza viene anche chiamata "stringa" se il tipo di carattere specificato è chiaro dal contesto. Nel resto di questa clausola, charT denota un tipo char simile. L'archiviazione per la stringa viene allocata e liberata, se necessario, dalle funzioni membro della classe basic_string, tramite la classe Allocator passata come parametro del modello. Allocator :: value_type deve essere uguale a char.
  2. Il modello di classe basic_string è conforme ai requisiti di una sequenza, come specificato in (23.1.1). Inoltre, poiché gli iteratori supportati da basic_string sono iteratori ad accesso casuale (24.1.5), basic_string è conforme ai requisiti di un container reversibile, come specificato in (23.1). ISO/IEC 14882: 2003 (E)  ISO/IEC 21.3 Modello di classe basic_string 21 Libreria di stringhe
  3. In tutti i casi, size() < = capacity().

E poi in C++ 17 hanno cambiato troppo

  1. Il basic_string template classe descrive oggetti che possono memorizzare una sequenza costituita da un numero variabile di oggetti char-like arbitrarie con il primo elemento della sequenza in posizione zero. Tale sequenza è anche chiamata "stringa" se il tipo di oggetti char-like che detiene è libero dal contesto. Nel resto di questa clausola , il tipo di oggetti tipo char contenuti in un oggetto basic_string è designato da char.
  2. Le funzioni membro di basic_string utilizzano un oggetto della classe Allocatore passato come parametro modello per allocare e del deposito per il char-like contenuta objects.233
  3. Una basic_string è un contenitore contiguo (23.2.1) .
  4. In tutti i casi, dimensioni() < = capacità().

sottolineatura mia

Quindi pre C++ 17 non era certo, ma ora lo è.

Con i vincoli imposti da std::string::data, questa non garanzia è quasi discutibile poiché chiamare std::string::data fornisce una matrice continua dei caratteri nella stringa. Quindi, a meno che l'implementazione non stia facendo ciò su richiesta e in un tempo costante, la stringa sarà continua.


Nel caso in cui si chiedono: Questo è importante se si dispone di codice passando il risultato di &str[0] a una funzione in attesa di un pezzo di memoria contiguo di scrivere. (So ​​di str.data(), ma per ovvie ragioni il vecchio codice non lo usa.)

Il comportamento di operator[] è cambiato pure. In C++ 03 abbiamo avuto

Ritorni: Se pos < size(), restituisce i dati() [pos]. Altrimenti, se pos == size(), la versione const restituisce charT(). Altrimenti, il comportamento non è definito.

Così è stata garantita solo la versione const ad aver definito il comportamento se si è tentato &s[0] quando s è vuoto. In C++ 11 hanno cambiato a:

Returns: * (begin() + pos) se pos < dimensioni(). In caso contrario, restituisce un riferimento a un oggetto di tipo char con valore charT(), in cui la modifica dell'oggetto conduce a un comportamento non definito.

Così ora entrambe le versioni const e non const hanno definito comportamento se si è tentato &s[0] quando s è vuoto.

+3

Non c'è modo di avere 'stringa :: data()' come funzione di tempo costante che restituisce una sequenza continua senza che l'archiviazione effettiva sia continua, anche in C++ 03 . –

+0

@Let_Me_Be Sì, ma se lo standard non impone il requisito, non si può essere certi che ciò accadrà il 100% delle volte. Sto immaginando una struttura simile a una deque. – NathanOliver

+0

Lo standard impone il requisito di 'string :: data()' che contiene lo stesso contenuto del contenuto della stringa e impone il requisito di tempo costante su 'string :: data()'. Non c'è modo di avere una struttura simile alla deque e mantenere la costante restrizione temporale. –

Problemi correlati