![](/img/trans.png)
[英]How to convert unsigned char[] to std::vector<unsigned char>
[英]How to convert std::vector<unsigned char> to vector<char> without copying?
我無法找到這個問題,這是我面臨的一個實際問題。
我有一個文件加載實用程序,它返回包含整個文件內容的std::vector<unsigned char>
。 但是,處理函數需要contiguos char
數組(並且不能更改 - 它是庫函數)。 由於使用處理函數的類仍然存儲數據的副本,我想將其存儲為vector<char>
。 這里的代碼可能更具說明性。
std::vector<unsigned char> LoadFile (std::string const& path);
class Processor {
std::vector<char> cache;
void _dataOperation(std::vector<char> const& data);
public:
void Process() {
if (cache.empty())
// here's the problem!
cache = LoadFile("file.txt");
_dataOperation(cache);
}
};
此代碼無法編譯,因為(顯然)沒有適當的轉換。 但是,我們可以肯定,臨時向量將占用相同數量的內存(IOW sizeof(char) == sizeof(unsigned char)
)
天真的解決方案是迭代臨時內容並投射每個角色。 我知道在正常情況下,將調用operator= (T&&)
。
在我的情況下,重新解釋轉換是安全的,因為我確信我只會讀取ASCII字符。 無論如何,任何其他角色都會被_dataOperation
捕獲。
所以,我的問題是: 如何以一種不涉及復制的方式正確安全地轉換臨時向量?
如果不可能,我寧願采用安全的復制方式而不是不安全的非復制方式。 我還可以更改LoadFile
以返回vector<char>
或vector<unsigned char>
。
在C ++ 11中,[basic.lval] p10說,
如果程序試圖通過以下類型之一以外的glvalue訪問對象的存儲值,則行為未定義:
- ...
- char或unsigned char類型。
(其他版本的C ++中的確切位置可能不同,但含義相同。)
這意味着您可以使用vector<unsigned char> cache
並使用范圍[reinterpret_cast<char*>(cache.data()), reinterpret_cast<char*>(cache.data()) + cache.size())
訪問其內容[reinterpret_cast<char*>(cache.data()), reinterpret_cast<char*>(cache.data()) + cache.size())
。 (@Kerrek SB提到了這一點。)
如果在Processor
存儲vector<unsigned char>
以匹配LoadFile
的返回類型,並且_dataOperation()
實際上采用char
數組(意味着const char*
和size),那么您可以在傳遞_dataOperation()
參數
但是,如果_dataOperation()
專門采用vector<char>
並存儲vector<unsigned char> cache
,則無法將其傳遞給reinterpret_cast<vector<char>&>(cache)
。 (即@AndréPuel完全錯了。不要聽他說。)這違反了別名規則,編譯器會在凌晨2點試圖激怒你的客戶。 (如果這個版本的編譯器沒有管理它,下一個版本將繼續嘗試。)
正如您所提到的,一個選項是模板LoadFile()
並讓它返回(或填充)您想要的類型的向量。 另一種方法是復制結果,簡潔版本再次是源向量的.data()
的reinterpret_cast
。 [basic.fundamental] p1提到“對於字符類型,對象表示的所有位都參與值表示。”,這意味着您不會丟失使用該reinterpret_cast
數據。 我沒有看到一個確定的保證,如果reinterpret_cast'ed
為char
,沒有unsigned char
位模式可能導致陷阱,但我不知道有任何現代硬件或編譯器這樣做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.