获取std :: vector指针的更好方法

3

由于&v[0]v.data()提供了相同的访问std::vector底层指针的方式,我想知道在稳定性和可移植性方面哪种方法更好?


3
由于std :: vector提供了一个data()成员函数,因此我不认为需要手动获取第一个元素的地址。唯一更好的选择是出于可读性考虑。 std :: vector将始终具有下标运算符,并且始终将具有data()成员,因此在稳定性和可移植性方面选择哪个不是问题^^ 它们基本上是相同的,并且都需要按照标准存在。 - Fareanor
3
cppreference 看来,指针的范围 [data(); data()+size()) 总是有效的,即使容器为空(在这种情况下,data() 不能被解引用)。但不确定在使用 &v[0] 时是否仍然成立。 - Adrian Mole
1
@AdrianMole 但是如果你进一步查看,他们提到如果向量为空,data() 可能会返回 nullptr。我不确定他们所说的“有效”范围是什么意思。 - Fareanor
1
@Fareanor 这里有一些讨论:https://dev59.com/Q18e5IYBdhLWcg3wucf-。 - Daniel Langr
1
@DanielLangr 哦,好的,感谢提供参考。这使得data()&v[0]更安全,因为后者会在容器为空时触发未定义行为(除非我弄错了)。 - Fareanor
5
今天我学到了一个编程知识:data是保证有效的。使用&v[0]会导致未定义行为,而std::vector::data保证返回有效值(尽管其返回值由具体实现决定)。看起来data是正确的方式...但在两种情况下仍然需要进行长度检查。 - erip
1个回答

14

来自cppreference

"返回值
指向基础元素存储的指针。对于非空容器,返回的指针与第一个元素的地址相等"

强调是我的

对于非空的std::vectorv.data()&v[0]都是相等的。所以在这一点上,选择哪一个只是个人偏好的问题。

但如果我们仔细看,还可以读到:

"返回指向作为元素存储的底层数组的指针。即使容器为空,该指针也是范围[data(); data()+size())始终是有效范围(在这种情况下,data()不可解引用)"

强调是我的

这意味着即使向量为空,您也可以使用由std::vector :: data()返回的指针(及其大小)上的迭代器工作的任何标准算法。
而通过取第一个元素的地址则不可能,因为对于空向量,通过下标操作符std::vector :: operator[]()访问值是未定义行为。
因此,我认为使用std::vector::data()是最好的选择。

1
旁注:当向量为空时,data() 可能会返回空指针值。在这种情况下,size() 为零,因此 data() + size() 是良好定义的,并且 [data(); data()+size()) 仍然是一个有效的范围。 - j6t
1
@j6t 是的,这正是我最后一段的重点。 - Fareanor
1
@MarkB 为什么它会效率更低?两者都是函数调用,“data()”基本上只返回受管理的指针。我甚至期望“data()”会更快,因为不需要指针算术或指针解引用。但编译器优化可能消除这种可能的差异。无论如何,如果您关心性能,请进行分析,否则,争论毫无意义。什么是“最好”的取决于给定的标准,而性能并未列在OP的列表中(但即使列在其中,我认为它至少与之一样有效,甚至更快)。 - Fareanor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接