Подтвердить что ты не робот

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&&);
4b9b3361

Ответ 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;
}