A parte (l'ovvio) costruire prima una stringa in stile C e poi usarla per creare uno std :: string, esiste un modo più veloce / alternativo / "migliore" per inizializzare una stringa da un vettore di caratteri?
A parte (l'ovvio) costruire prima una stringa in stile C e poi usarla per creare uno std :: string, esiste un modo più veloce / alternativo / "migliore" per inizializzare una stringa da un vettore di caratteri?
Risposte:
Penso che tu possa semplicemente fare
std::string s( MyVector.begin(), MyVector.end() );
dove MyVector è il tuo std :: vector.
_ITERATOR_DEBUG_LEVEL=1(nel qual caso sembra funzionare bene).
Con C ++ 11, puoi fare std::string(v.data())o, se il tuo vettore non contiene un '\0'alla fine std::string(v.data(), v.size()),.
string(&v[0], v.size())dovrebbe funzionare anche, ma solo dopo assert(not v.empty());, poiché se il vettore è vuoto, entrambi v[0]e v.front()invocerebbero un comportamento indefinito. Questo, a parte la semplicità sintattica di non dover usare l'operatore address-of, è il vero vantaggio della funzione di C ++ 11 data(), che funziona anche su un vettore vuoto.
std::string(v.data())potrebbe portare una stringa più lunga. Quindi non usare in questo modo.
std::string(v.data(), v.size()), che è stato esplicitamente menzionato nella risposta per questo motivo esatto?
std::string s(v.begin(), v.end());
Dove v è praticamente qualsiasi cosa iterabile. (In particolare, begin () e end () devono restituire InputIterators.)
Solo per completezza, un altro modo è std::string(&v[0])(anche se è necessario assicurarsi che la stringa sia terminata da null e std::string(v.data())generalmente è da preferire.
La differenza è che puoi usare la prima tecnica per passare il vettore alle funzioni che vogliono modificare il buffer, cosa che non puoi fare con .data ().
data()per modificare il buffer? Mi sembra che se chiami data()su un vettore non const, restituirà a T *(e se il tuo vettore è const, 'v [0] `restituirebbe T const &comunque a).
vfosse una stringa, ma il tipo di destinazione è una stringa ed vè un vettore. (Ma è bello vedere che C ++ 17 darà la parità delle stringhe con il vettore.)
Mi piace la risposta di Stefan (11 settembre 13) ma vorrei renderla un po 'più forte:
Se il vettore termina con un terminatore nullo, non dovresti usare (v.begin (), v.end ()): dovresti usare v.data () (o & v [0] per quelli precedenti a C ++ 17) .
Se v non ha un terminatore nullo, dovresti usare (v.begin (), v.end ()).
Se usi begin () e end () e il vettore ha uno zero terminale, ti ritroverai con una stringa "abc \ 0", ad esempio, che è di lunghezza 4, ma dovrebbe essere solo "abc".
vector<char> vec;
//fill the vector;
std::string s(vec.begin(), vec.end());
std::vector<char> v2(std::move(v))ma con unstd::stringoggetto nuovo.