std::tuple 内存对齐 [英] std::tuple memory alignment

查看:46
本文介绍了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))

这篇关于std::tuple 内存对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆