2012-05-04 41 views
12

Tôi đang làm việc với 2 thư viện. Một người nhận và trả về std::string trong khi người kia sử dụng std::vector<unsigned char> s.std :: di chuyển giữa std :: string và std :: vector <unsigned char>

Sẽ tốt nếu tôi có thể lấy cắp các mảng cơ bản từ std::stringstd::vector<unsigned char> và có thể di chuyển chúng vào nhau mà không cần sao chép quá mức.

ATM tôi sử dụng một cái gì đó như:

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

Và cách khác:

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

Nó muốn được tốt hơn để có thể xác định một:

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

Trả lời

7

Điều này là không thể.

Các vectorstring lớp không cung cấp cách để ăn cắp từ bất cứ điều gì khác hơn vector hoặc stringtương ứng. Chúng không có nghĩa là trao đổi nội dung.

Sự cố vấn đề là vectorstring có thể có các đại diện cơ bản khác nhau. Điển hình trong gcc chẳng hạn, string sử dụng tính năng tối ưu hóa COW cũ (Sao chép khi viết), khác với biểu diễn điển hình của vector (thường chỉ là ba thuộc tính con trỏ/size_t).

Nếu bạn đang xử lý byte thô, đổ lỗi cho thư viện đã quyết định đặt chúng vào string và tái cấu trúc nó nếu bạn có thể.

Nếu không: sao chép. Không cần thiết phải có reinterpret_castcharunsigned char có các phôi tiềm ẩn giữa chúng (và bây giờ char thường là unsigned theo mặc định).

+1

C++ 11 rõ ràng không cho phép sao chép trên ghi, phải không? Trừ khi họ giữ nó dưới "miễn là nó hoạt động như thể chúng tôi tuân thủ luật" cụ thể ". Tôi nghĩ rằng tối ưu hóa chuỗi nhỏ đã là con đường để đi một lúc. –

10

Bạn có thể sử dụng khởi tạo bằng cách sử dụng vòng lặp. Có một cái nhìn here

CHỈNH SỬA: dán mã để bạn không phải đi tới ideone. Vẫn rời khỏi liên kết để bạn có thể chơi arround với mã

#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

Tất nhiên điều này không khác biệt gì với giải pháp của anh ấy, liên quan đến các bản sao cần thiết (câu hỏi của anh ấy là gì) và do đó không trả lời câu hỏi của anh ấy theo bất kỳ cách nào. Nó sạch hơn nhiều so với giải pháp của ông, tuy nhiên, nhưng một bình luận sẽ có đủ cho điều này. –

+0

@Christian tại sao sạch hơn nhiều? 'string & assign (const char * s, size_t n);' nên làm một memcpy, trong khi 'template string & assign (InputIterator đầu tiên, InputIterator last); 'giả lập nó – Liviu

Các vấn đề liên quan