【问题标题】:Can I be sure a vector contains objects and not pointers to objects?我可以确定向量包含对象而不是指向对象的指针吗?
【发布时间】:2021-12-12 16:13:42
【问题描述】:

我能否确定std::vector(或者一般来说,任何标准容器)包含对象而不是指向对象的指针,无论对象的类有多复杂,如果它具有恒定大小?

例如:在这个简单的例子中:

struct MyStruct { int a, b; };
std::vector<MyStruct> vs;

生成的矢量布局为:

[ ..., a1, b1, a2, b2, a3, b3, ... ]

标准是否保证在这种(或更复杂的)情况下也会发生同样的情况,其中结构的大小应该是恒定的:

struct MyStruct2 { float f[10]; };
std::vector<MyStruct2> vs2;

带布局:

[ ..., f1[0], f1[1], ..., f1[9], f2[0], f2[1], ..., f2[9], ... ]

代替:

[ ..., *pf1, *pf2, ... ]
pf1 = [ f1[0], f1[1], ..., f1[9] ]
pf2 = [ f2[0], f2[1], ..., f2[9] ]

【问题讨论】:

  • 即使在您的简单MyStruct 情况下,您也不一定会假设a2 在内存中紧跟b1,因为编译器是free to add padding to your struct。您可以做出的唯一假设是元素 [1] 恰好是 sizeof(MyStruct) 与 [0] 的偏移量。
  • std::vector&lt;T&gt; 持有Ts, std::vector&lt;T*> 持有T*s。
  • 你可以使用类型特征对其进行 sfinae,也许是一个 create_vector 函数,它只需要 std::enable_if...en.cppreference.com/w/cpp/types/is_pointer
  • 这里有两个不同的点,(1)std::vector 将根据您提供的模板参数(如果您提供指针类型@987654341 @,它存储指针类型)(2)如果你想要一个不能保存指针类型的向量,你可以在 std::vector 周围做一个薄包装,并使用 SINFAE 来阻止指针类型或从类型中删除指针。
  • 对象按顺序存储在内存中。如果你有一个指针向量,你只会得到指向对象的指针,在这种情况下,这些指针将按顺序存储在内存中。 (指针本身就是一个对象。)

标签: c++ pointers containers stdvector


【解决方案1】:

由于 C++11 及更高版本(C++03几乎保证),std::vector 中的数据是连续的,没有间隙。

特别是如果您有一个指向 std::vector 中的元素的指针,则可以使用指针算法访问所有其他元素。

当然,指针运算以struct 的sizeof 为单位工作。 struct 本身可能包含填充。尝试到达b 时的行为,在你的结构中给定一个指向a 的指针是未定义的。

【讨论】:

  • 这更好地表达了我试图在 cmets 中闲逛的内容,+1
  • 臭名昭著的异常std::vector&lt;bool&gt;
  • 我认为您实际上并没有回答问题。据我了解,问题 OP 想知道他们是否可以对向量元素的 f 的元素使用指针算术以达到下一个向量元素的 f,但MyStruct2 中可能有填充
猜你喜欢
  • 2020-12-06
  • 2021-08-05
  • 2021-08-25
  • 2013-07-12
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
相关资源
最近更新 更多