За винятком (очевидного) побудови рядка стилю C спочатку, використовуючи це для створення std :: string, чи існує швидший / альтернативний / "кращий" спосіб ініціалізації рядка з вектора символів?
За винятком (очевидного) побудови рядка стилю C спочатку, використовуючи це для створення std :: string, чи існує швидший / альтернативний / "кращий" спосіб ініціалізації рядка з вектора символів?
Відповіді:
Я думаю, ти можеш просто зробити
std::string s( MyVector.begin(), MyVector.end() );
де MyVector - ваш std :: vector.
_ITERATOR_DEBUG_LEVEL=1(у такому випадку, здається, це працює нормально).
З C ++ 11, ви можете зробити , std::string(v.data())або, якщо вектор не містить '\0'в кінці std::string(v.data(), v.size()).
string(&v[0], v.size())слід працювати, але тільки після assert(not v.empty());, оскільки, якщо вектор порожній, обидва v[0]і v.front()викликатимуть невизначене поведінку. Це, окрім синтаксичної простоти відсутності використання оператора адреси адреси, є реальною перевагою функції C ++ 11 data(), яка працює навіть у порожньому векторі.
std::string(v.data())може призвести до довшого рядка. Тому не використовуйте цей спосіб.
std::string(v.data(), v.size()), що було прямо вказано у відповіді саме з цієї причини?
std::string s(v.begin(), v.end());
Де v майже все, що можна відтворити. (Спеціально start () та end () повинні повернути InputIterators.)
Для повноти, інший спосіб є std::string(&v[0])(хоча вам потрібно переконатися, що ваш рядок є недійсним і, std::string(v.data())як правило, бажано.
Різниця полягає в тому, що ви можете використовувати колишню техніку для передачі вектора функціям, які хочуть змінити буфер, що ви не можете зробити з .data ().
data()для зміни буфера? Мені це здається, якщо ви зателефонуєте data()за неконст-вектором, він поверне a T *(а якщо ваш вектор const, 'v [0] `повернеться у T const &будь-якому випадку).
vбув рядок, але цільовий тип - це рядок і vє вектором. (Але приємно бачити, що C ++ 17 дасть рядки парності з вектором.)
Мені подобається відповідь Стефана (11 вересня 1313 р.), Але я хотів би зробити її трохи сильнішою:
Якщо вектор закінчується нульовим термінатором, ви не повинні використовувати (v.begin (), v.end ()): ви повинні використовувати v.data () (або & v [0] для тих, хто до C ++ 17) .
Якщо v не має нульового термінатора, слід використовувати (v.begin (), v.end ()).
Якщо ви використовуєте start () і end (), а вектор має кінцевий нуль, ви отримаєте рядок "abc \ 0", наприклад, довжиною 4, але насправді має бути лише "abc".
vector<char> vec;
//fill the vector;
std::string s(vec.begin(), vec.end());
std::vector<char> v2(std::move(v))зstd::stringновим об'єктом.