Std:: move между std::string и std::vector <unsigned char>
Я работаю с 2 библиотеками. Один принимает и возвращает std::string
, в то время как другой использует std::vector<unsigned char>
s.
Было бы хорошо, если бы я мог украсть базовые массивы из std::string
и std::vector<unsigned char>
и иметь возможность перемещать их друг в друга без чрезмерного копирования.
ATM Я использую что-то вроде:
const unsigned char* raw_memory =
reinterpret_cast<const unsigned char*>(string_value.c_str()),
std::vector<unsigned char>(raw_memory, raw_memory + string_value.size();
И наоборот:
std::string(
reinterpret_cast<const char*>(&vector_value[0]),
vector_value.size());
Было бы намного лучше определить a:
std::string move_into(std::vector<unsigned char>&&);
std::vector<unsigned char> move_into(std::string&&);
Ответы
Ответ 1
Это невозможно.
Класс vector
и string
не предоставляет способ украсть ничего, кроме vector
или string
соответственно. Они не предназначены для обмена контентом.
Проблема заключается в том, что vector
и string
могут иметь самые разные базовые представления. Обычно в gcc, например, string
используется старая кошка (копирование по записи) "оптимизация", которая сильно отличается от типичного представления vector
(обычно это всего лишь тройка указателей/размер_татрибутов).
Если вы имеете дело с необработанными байтами, обвините библиотеку, которая решила поместить ее в string
, и реорганизовать ее, если сможете.
В противном случае: скопируйте. reinterpret_cast
не обязательно, потому что char
и unsigned char
имеют неявные отбрасывания между ними (а теперь char
часто unsigned
по умолчанию).
Ответ 2
Инициализацию можно использовать с помощью итераторов. Посмотрите здесь
РЕДАКТИРОВАТЬ: вставьте код, чтобы вам не приходило в идеон. Все еще оставляя ссылку, чтобы вы могли играть arround с кодом
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string a = "Hello world";
vector<unsigned char> v(a.begin(), a.end());
for (int i= 0 ;i< v.size(); ++i) {
cout << v[i] << endl;
}
string s(v.begin(), v.end());
cout << s << endl;
return 0;
}