[英]Difference in memory layout of vector of pairs and vector of structs containing two elements - C++/STL
test1
和test2
的内存布局是否相同?
std::vector<std::pair<int,int> > test1;
std::vector<mystruct> test2;
其中mystruct定义为:
struct mystruct{
int a;
int b;
};
逻辑上, std::pair<int, int>
应该被定义。
然而,标准上没有任何相关内容,而且完全没有保障。 您可以查看编译器中的头文件来确认,但这并不能证明什么。
注意:如果您认为不这样做是荒谬的,我可以举例说明如何定义它。 想象一下在使用std::pair
的其他stl模板类中,他们觉得在对中有一个指向包含该对的节点的指针是方便的(出于任何原因)。 这样,他们可以在内部添加指向对类的指针,同时不违反任何规则。 你的假设会造成严重破坏。 我会说他们不太可能做这样的事情,是的,但只要他们没有被迫采用这种布局,任何事情都可能发生。
如果你在cplusplus.com上看到,你会发现这是一对的结构:
template <class T1, class T2> struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair() : first(T1()), second(T2()) {}
pair(const T1& x, const T2& y) : first(x), second(y) {}
template <class U, class V>
pair (const pair<U,V> &p) : first(p.first), second(p.second) { }
}
完全相同,我会说,除了一些事实:好吧,从对与std容器兼容的事实开始,例如,映射。 此外,这些对已经制作好了,并且已经有了构造函数。
编辑:我也忘了提到你将拥有std :: make_pair,允许你跳过分配内存并在结构中创建自己的对,并且你也定义了一些比较和赋值运算符。
是的,至少在发布模式下它的大小相同。
你不应该使用这些知识做一些记忆诡计,原因有两个:
1)std使用了很多额外的调试工具。 这使得类的大小在调试和发布模式下有所不同。 所以很可能std :: pair在调试模式下更大。
2)std可能会在内部发生变化。 无法保证std :: pair不会在不同的std版本中更改它的内存布局。 因此,如果您依赖于此,您必须忍受有一天它可能不再起作用的恐惧。
在std::pair
任何合理实现中,它们将具有相同的布局。 但这引出了为什么重要的问题? 你不应该从一个到另一个进行二进制赋值。
您可以直接或通过子类化将结构构造函数添加到结构中。 您还可以添加以相反方式执行转换的方法。
struct mystruct{
int a;
int b;
mystruct(const std::pair<int,int> &rhs) { a=rhs.first; b=rhs.second; }
std::pair<int,int> as_pair() { return std::make_pair(a, b); }
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.