假設我有花車的載體,我想「連載」,爲缺乏一個更好的詞,轉換爲字節向量,即從POD矢量數據複製到字節(乾淨)的矢量
std::vector<float> myFloats = {1.0, 2.0, 3.0, 4.0};
std::vector<unsigned char> myBytes;
現在,我浮動到一個uint32_t
變量,並執行位移位和掩碼一次插入一個字節到myBytes
。
由於這兩者的內存是連續的,有沒有辦法讓我更乾淨地做到這一點?
假設我有花車的載體,我想「連載」,爲缺乏一個更好的詞,轉換爲字節向量,即從POD矢量數據複製到字節(乾淨)的矢量
std::vector<float> myFloats = {1.0, 2.0, 3.0, 4.0};
std::vector<unsigned char> myBytes;
現在,我浮動到一個uint32_t
變量,並執行位移位和掩碼一次插入一個字節到myBytes
。
由於這兩者的內存是連續的,有沒有辦法讓我更乾淨地做到這一點?
你允許使用unsigned char *
別名成其他類型在不違反嚴格走樣,所以下面的工作
std::vector<float> myFloats = {1.0, 2.0, 3.0, 4.0};
std::vector<unsigned char> myBytes{reinterpret_cast<unsigned char *>(myFloats.data()),
reinterpret_cast<unsigned char *>(myFloats.data() + myFloats.size())};
你利用這需要兩個迭代器
template< class InputIt >
vector(InputIt first, InputIt last,
const Allocator& alloc = Allocator());
的
vector
constructor的
我不認爲這將工作,因爲myFloats.size()只有4,但每個浮動需要多個字節,在你的例子中,你只會複製第一個浮動(在32位系統中)。我認爲這應該是myFloats.data()+(myFloats.size()* sizeof(float))爲結束迭代器。 – AngelCastillo
@AngelCastillo這不是數學指針的工作原理。 'myFloats.data()'向第一個'float'返回一個'float *',並且將其遞增4會得到一個指向'vector'中最後一個'float'的指針。你建議的解決方案將嘗試複製16個浮點數(假設'sizeof(float)== 4' – Praetorian
@Preatorian這對於指向float *的指針是正確的,但是你將指針指向「unsigned char *」,該構造函數會將該指針按「unsigned char」大小遞增,而不是「float」大小,最終結果將是指針每次移動一個字節四次。運行代碼,您將看到。 ,memcpy以void *作爲參數,這就是爲什麼我通過sizeof(float)多重化 – AngelCastillo
你可以這樣做:
std::vector<unsigned char>
getByteVector(const std::vector<float>& floats)
{
std::vector<unsigned char> bytes(floats.size() * sizeof(float));
std::memcpy(&bytes[0], &floats[0], bytes.size());
return bytes;
}
這工作正常,但請注意矢量構造函數將初始化值(初始化爲零)全部'unsigned c在你用'memcpy'覆蓋它們之前,所以會增加成本。 – Praetorian
@Preatorian是的,你的代碼更有效率:)。 – AngelCastillo
下面的兩個答案都是goo d,但假設數據將在具有相同字節序的系統上反序列化。現在大多數系統似乎都支持little-endian數據,但如果您將此發送給未知系統,則需要小心。有嵌入式系統(特別是網絡機器),仍然使用大端 –