对于元组的伪成员的布局和内存对齐是否有任何正式规范?
是否需要修改元组中类型的内存对齐方式?它是否受#杂注包()指令的影响?
例如:
typedef std::tuple<uint8_t, uint32_t> myTuple;是否有任何规范表明内存中的内容与以下相同:
#pragma pack() // Default packing
struct myStruct
{
uint8_t first;
uint32_t second;
}很抱歉,如果这是一个愚蠢的问题,但当涉及到模板时,我并不完全理解对齐。
编辑:我正在努力实现的例子
目前我有一些关于..。
#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<uint32, uint32, uint32>,那么我仍然能够读写元组的原始内存(因此是元组的向量),还是该内存具有未知的对齐方式?
发布于 2013-01-30 16:30:51
元组通常不是标准布局,因为标准布局类最多只能有一个具有非静态数据成员的继承层次结构中的类,而实现变量tuple的典型方法是通过递归继承,每个递归级别都添加一个数据成员。这允许tuple实现通过空基类优化来删除不同的空成员,这对于struct成员是不可用的。
如果您检查该sizeof(myTuple) == sizeof(myStruct),您就可以合理地假设元组的内存布局以某种(一致)顺序包含结构元素,但实际上依赖它进行混叠可能会导致未定义的行为。
如果就像您说的那样,您只想使用tuple的别名来进行元编程,那么最好使用元编程库(如Boost.Fusion )来注释结构类型及其成员:
#pragma pack(push)
#pragma pack(4)
struct cTriangle {
uint32 Index[3];
};
#pragma pack(pop)
BOOST_FUSION_ADAPT_STRUCT(
cTriangle,
(uint32[3], Index))发布于 2013-01-30 05:09:08
不仅不需要以任何特定的方式排列对象,而且许多tuple实现实际上将第二个对象放在第一个对象之前。
发布于 2013-01-30 14:35:24
正如大卫所指出的,按照标准是没有保证的。但是,如果您对两个值元组感兴趣,您可能需要使用std::pair<T1, T2>,它是标准布局(如果T1,T2是标准布局),因此具有可预测的内存布局。
编辑
对不起,在回答您的评论之前,我还没有看到ecatmur的答复。顺便说一句:如果您的结构的所有成员都具有相同的类型,当然可以使用std::array,这是标准布局,允许使用std::get访问元素,类似于std::tuple。
https://stackoverflow.com/questions/14597006
复制相似问题