Oprócz (oczywistego) zbudowania najpierw łańcucha w stylu C, a następnie użycia go do stworzenia std :: string, czy istnieje szybszy / alternatywny / „lepszy” sposób inicjalizacji łańcucha z wektora znaków?
Oprócz (oczywistego) zbudowania najpierw łańcucha w stylu C, a następnie użycia go do stworzenia std :: string, czy istnieje szybszy / alternatywny / „lepszy” sposób inicjalizacji łańcucha z wektora znaków?
Odpowiedzi:
Myślę, że możesz to zrobić
std::string s( MyVector.begin(), MyVector.end() );
gdzie MyVector jest twoim std :: vector.
_ITERATOR_DEBUG_LEVEL=1(w takim przypadku wydaje się działać dobrze).
Z C ++ 11, można to zrobić std::string(v.data())albo, jeśli wektor nie zawiera '\0'na końcu std::string(v.data(), v.size()).
string(&v[0], v.size())powinno również działać, ale tylko później assert(not v.empty());, ponieważ jeśli wektor jest pusty, oba v[0]i v.front()wywołałyby niezdefiniowane zachowanie. To, poza prostotą składni, polegającą na tym, że nie trzeba używać operatora address-of, jest prawdziwą zaletą funkcji C ++ 11 data(), która działa nawet na pustym wektorze.
std::string(v.data())może prowadzić do dłuższego ciągu. Więc nie używaj w ten sposób.
std::string(v.data(), v.size()), co zostało wyraźnie wymienione w odpowiedzi właśnie z tego powodu?
std::string s(v.begin(), v.end());
Gdzie v jest praktycznie dowolną iteracją. (W szczególności begin () i end () muszą zwracać InputIterators.)
Dla kompletności, inny sposób to std::string(&v[0])(chociaż musisz upewnić się, że twój łańcuch jest zakończony znakiem null i std::string(v.data())generalnie jest preferowany.
Różnica polega na tym, że możesz użyć poprzedniej techniki, aby przekazać wektor do funkcji, które chcą zmodyfikować bufor, czego nie można zrobić za pomocą .data ().
data()zmodyfikować bufora? Wydaje mi się, że jeśli wywołasz data()wektor inny niż const, zwróci on a T *(a jeśli twój wektor to const, 'v [0]' i T const &tak zwróci a ).
vbył ciągiem, ale typ docelowy jest ciągiem i vjest wektorem. (Ale fajnie jest widzieć, że C ++ 17 da ciągi parzystość z wektorem.)
Podoba mi się odpowiedź Stefana (wrzesień 11 '13), ale chciałbym ją nieco wzmocnić:
Jeśli wektor kończy się terminatorem zerowym, nie powinieneś używać (v.begin (), v.end ()): powinieneś używać v.data () (lub & v [0] dla tych sprzed C ++ 17) .
Jeśli v nie ma terminatora zerowego, należy użyć (v.begin (), v.end ()).
Jeśli użyjesz funkcji begin () i end (), a wektor ma kończące zero, otrzymasz na przykład łańcuch „abc \ 0”, który ma długość 4, ale w rzeczywistości powinien mieć tylko „abc”.
vector<char> vec;
//fill the vector;
std::string s(vec.begin(), vec.end());
std::vector<char> v2(std::move(v))ale z astd::stringjako nowym obiektem.