2011-03-05 66 views
5

经过一番调查后,我发现C++ 0x将元组中的元素向后存储在内存中。C++ 0x元组存储元素向后

例如,利用这个代码:

std::tuple<char, char, char> x('\0', 'b 'a'); 
char* y = (char*)&x; 
std::cout << sizeof(x) << std::endl; 
std::cout << y << std::endl;

当与GCC 4.5.2编译,我得到以下的输出:

3 
ab

这最初我迷惑不解。为什么数据存储倒退?通过GNU的无意混淆头狩猎后,我注意到,实施类似于此:

template<typename head, typename... tail> class tuple<head, tail...> : public tuple<tail...> 
{ 
    head value; 
    ... 
};

因为基类中包含的最后一个元素,那么下一个派生类中包含了倒数第二,等等,实际模板参数的顺序相反。

当我第一次进入元组时,我认为我可以将它们用于像glInterleavedArrays()这样的函数,它将顶点数据的数组设置为颜色,纹理坐标,法线和点的元组。当然,如果我创建了一个元组数组,这些数据将不得不反向输入,如果您忘记将参数按正确的顺序排列,这可能会导致非常奇怪的错误。

那么这样的事情呢?

template<typename... head, typename tail> class tuple<head..., tail> : public tuple<head...> 
{ 
    tail value; 
    ... 
};

下GCC 4.5.2:

error: parameter pack argument ‘head ...’ must be at the end of the template argument list

除非本可用在未来,我几乎停留在寻找另一种方式来实现这一点。有另一种方法吗?一些欺骗海湾合作委员会获得一个正确排序的元组记忆方式?

回答

5

您正在探索的元组布局是未指定的元组实现细节。其他实现将有其他布局。如果你写这个,根据gcc的布局,你的代码可能不能移植到其他std :: libs。

libc++元组实现(例如)具有相反的(按顺序)布局。

5

你为什么在乎元组的实现是什么? Program to an interface, not an implementation

如果您只通过其公布的接口使用元组,那么您将按照您将其放入的顺序排列对象。如果您直接通过访问其内容来破坏封装,例如通过在您的例如,所有投注都关闭。

+0

我已经说过为什么 - 'glInterleavedArrays()'是一个请求交错数据数组的函数。我的意图是创建一个元组类,它将按照这个原则进行操作 - 将数据交织在元组数组中,以便我可以将数据传递给GL。如果你想了解更多信息,请参阅OpenGL文档:http://www.opengl.org/sdk/docs/man/xhtml/glInterleavedArrays.xml – 2011-03-05 21:22:08

+0

@RetroX:然后而不是依靠元组的实现,你需要一个对象其接口以已知的顺序提供序列化手段。无论哪种方式,您都希望接口提供保证,以便您不受实施细节的限制。 – 2011-03-05 21:51:37