我需要处理由一系列POD元素组成的记录。
在处理一系列这些记录之前,会在运行时找到这些元素的类型。理想情况下,记录的存储将连续地容纳元素,以便可以直接填充存储或通过系统IO调用输出存储。
给出以下简化的示例代码:
template<typename T>
struct ElementAccessor {
ElementAccessor(int offset)
:
_offset(offset)
{}
T &operator () (void * data)
{
return reinterpret_cast<T &>(
*reinterpret_cast<char *>(data) + _offset);
}
int _offset;
};
ElementAccessor<float> fEl(0);
ElementAccessor<int> iEl(sizeof(float));
我正在寻找一种有效且方便的方式来存储记录吗?
我考虑了以下方法:
vector<int>
使用
vector<int>
似乎很方便:std::vector<int> intData(2);
iEl(intData.data()) = 42;
fEl(intData.data()) = 12.4f; //< Uh-oh, undefined behaviour, maybe zero initialization could be reordered after this point!
但会违反严格混叠规则。
Raw allocated memory
我相信以下是有效的代码,但是由于内存管理是手动的,因此不方便:
void *voidData(operator new(2 * sizeof(int)));
iEl(voidData) = 42;
fEl(voidData) = 12.4f;
...
operator delete(voidData);
std::vector<char>
如何使用
std::vector<char>
:std::vector<char> charData(2 * sizeof(int));
iEl(charData.data()) = 42;
fEl(charData.data()) = 12.4f;
便利的是
std::vector
很好地处理了内存管理。但这有效吗?
最佳答案
根据标准,由于违反严格的混叠和对齐方式,因此您提出的所有选项都不正确。
您可以做的是在缓冲区的任意偏移量与您选择的类型之间的memcpy
。但是没有对数据“就地”进行操作。