std::tuple 内存对齐
对于元组的伪成员的布局和内存对齐是否有任何正式的规范?
Is there any formal specification for the layout and memory alignment for the pseudo members of a tuple?
有没有办法修改元组中类型的内存对齐方式?是否受#pragma pack() 指令影响?
Is there anyway to modify the memory alignment of types in a tuple? Is it effected by a #pragma pack() directive?
例如:
typedef std::tuple<uint8_t, uint32_t> myTuple;
是否有任何规范说明这将在内存中与以下内容相同:
Is there any specification that says this will be in memory the same as:
#pragma pack() // Default packing
struct myStruct
{
uint8_t first;
uint32_t second;
}
抱歉,如果这是一个愚蠢的问题,但我不完全理解模板的对齐方式.
Apologies if this is a stupid question but I don't entirely understand alignment when it comes to templates.
我正在尝试完成的示例
目前我有一些类似...
Currently I have something along the lines of...
#pragma pack(push)
#pragma pack(4)
struct cTriangle
{
uint32 Index[3];
};
#pragma pack(pop)
template <class T>
inline bool Read(cFileStream& fStream, std::vector<T>& vec)
{
if (!vec.size())
return true;
// fStream.Read(void* pBuffer, size_t Size)
// Just a wrapper around a binary ifstream really
return fStream.Read(&vec[0], sizeof(T) * vec.size());
}
std::vector<cVector3> vPoint;
vPoint.resize(Verticies);
bool result = Read(FileStream, vPoint);
如果我想将 cTriangle
键入为 std::tuple
用于元编程目的,我仍然可以读取/写入原始数据吗?元组的内存(因此是元组的向量)还是该内存具有未知的对齐方式?
If I wanted to typedef cTriangle
as std::tuple<uint32, uint32, uint32>
for metaprogramming purposes would I still be able to read/write to the raw memory of the tuple (and thus a vector of tuples) or would that memory have unknown alignment?
推荐答案
元组通常不是标准布局的,因为标准布局的类在其继承层次结构中最多可以有一个具有非静态数据成员的类,而典型的实现可变参数 tuple
的方法是通过递归继承,每一级递归添加一个数据成员.这允许 tuple
实现通过空基类优化来删除不同的空成员,这对 struct
成员不可用.
Tuples are typically not standard-layout, because standard-layout classes can have at most one class in their inheritance hierarchy with non-static data members, and the typical way to implement variadic tuple
is through recursive inheritance, with each level of recursion adding one data member. This allows tuple
implementations to elide distinct empty members through the empty base class optimisation, which is not available for struct
members.
如果您检查 sizeof(myTuple) == sizeof(myStruct)
,您就有理由假设元组的内存布局以某种(一致的)顺序包含结构的元素,但实际上依赖于别名可能会导致未定义的行为.
If you check that sizeof(myTuple) == sizeof(myStruct)
, you are reasonably entitled to assume that the memory layout of the tuple contains the elements of the struct in some (consistent) order, but actually relying on that for aliasing will likely cause undefined behaviour.
如果你说你只是想用 tuple
作为元编程的别名,你最好使用元编程库,例如 Boost.Fusion 允许您使用其成员注释结构类型:
If as you say you just want alias with tuple
for metaprogramming, you'd be better off using a metaprogramming library such as Boost.Fusion that allows you to annotate the struct type with its members:
#pragma pack(push)
#pragma pack(4)
struct cTriangle {
uint32 Index[3];
};
#pragma pack(pop)
BOOST_FUSION_ADAPT_STRUCT(
cTriangle,
(uint32[3], Index))
相关文章