2012-05-04 27 views
12

Pracuję z 2 bibliotekami. Jeden pobiera i zwraca std::string s, podczas gdy drugi używa std::vector<unsigned char> s.std :: move między std :: string i std :: vector <unsigned char>

Byłoby dobrze, gdybym mógł ukraść podstawowe tablice z std::string i std::vector<unsigned char> i móc przenosić je do siebie bez nadmiernego kopiowania.

ATM używać coś takiego:

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(); 

a drugi sposób:

std::string(
    reinterpret_cast<const char*>(&vector_value[0]), 
    vector_value.size()); 

Byłoby o wiele lepiej, aby móc zdefiniować:

std::string move_into(std::vector<unsigned char>&&); 
std::vector<unsigned char> move_into(std::string&&); 

Odpowiedz

7

Nie jest to możliwe.

vector i string klasa nie dostarczają sposób okradać cokolwiek innego niż vector lub stringodpowiednio. Nie są przeznaczone do wymiany treści.

Problem z tym, że vector i string mogą mieć bardzo różne reprezentacje. Zazwyczaj w gcc na przykład, string używa starszej wersji "Optymalizacja", która jest bardzo różna od typowej reprezentacji vector (zwykle tylko potrójne wskaźniki/size_t atrybuty).

Jeśli masz do czynienia z surowymi bajtami, winić bibliotekę, która zdecydowała się umieścić je w string, i zreorganizować, jeśli możesz.

W przeciwnym razie: skopiuj. Numer reinterpret_cast nie powinien być konieczny, ponieważ char i unsigned char mają domyślne rzuty pomiędzy nimi (a teraz char jest często unsigned domyślnie).

+1

C++ 11 jawnie zakazuje kopiowania przy zapisie, prawda? Chyba że trzymają go pod "tak długo, jak zachowuje się tak, jakbyśmy postępowali zgodnie z prawem". Wydaje mi się, że mała optymalizacja ciągów to sposób, aby przejść na chwilę. –

10

You może użyć inicjalizacji za pomocą iteratorów. Zobacz, co to jest: here

EDYCJA: wklejenie kodu, dzięki czemu nie musisz iść do ideału. Nadal pozostawia link, aby można było zagrać w całość z kodem

#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; 
} 
+1

Oczywiście nie różni się to od jego rozwiązania, jeśli chodzi o potrzebne kopie (o co w nim chodzi) i w związku z tym nie odpowiada w jakikolwiek sposób na jego pytanie. Jest to o wiele czystsze niż jego rozwiązanie, ale wystarczyłby do tego komentarz. –

+0

@Chrześcijanin, dlaczego o wiele czystsze? 'string & assign (const char * s, size_t n);' powinno wykonać memcpy, podczas gdy 'template string & assign (najpierw InputIterator, InputIterator last); 'emuluje to – Liviu

Powiązane problemy