当您想要将std :: vector作为C数组访问时,您可以从至少四种不同的方式中进行选择,如本例所示:
#include <iostream>
#include <vector>
using namespace std;
int main() {
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(42);
vec.push_back(24024);
{
int* arr = vec.data();
cout << arr << endl; /* output: 0x9bca028 */
cout << arr[3] << endl; /* output : 24024 */
}
{
int* arr = &vec.front();
cout << arr << endl; /* output: 0x9bca028 */
cout << arr[3] << endl; /* output : 24024 */
}
{
int* arr = &vec[0];
cout << arr << endl; /* output: 0x9bca028 */
cout << arr[3] << endl; /* output : 24024 */
}
{
int* arr = &vec.at(0);
cout << arr << endl; /* output: 0x9bca028 */
cout << arr[3] << endl; /* output : 24024 */
}
}
我在大多数情况下找到的是&vec[0]
。我认为这是最不优雅的,所以......为什么它最常用?是更高效还是更兼容?我找不到关于data()
的大量文档。
答案 0 :(得分:17)
data()
对于C ++ 11来说是全新的,这就是为什么你不经常看到它。使用&vec.front()
的想法从来没有发生在我身上,可能是因为我使用operator[]
的次数比front()
更多(几乎从不)。我想其他人也一样。
答案 1 :(得分:17)
如果您使用的是C ++ 11,那么使用data()
绝对是首选。特别是,如果向量为空,则使用其他两个选项中的任何一个都会产生未定义的行为!如果您没有使用C ++ 11,并且向量可能为空,那么请务必检查该条件。
答案 2 :(得分:5)
使用&amp; vec [0]是最常见的,但我同意,确实看起来有点奇怪。有一点要记住未来。如果你的向量碰巧是一个对象的向量,它的类重载了运算符&amp;(),那么如果你调用&amp; vec [0]就会意识到这会导致奇怪的行为。
这将不会获得内部连续对象数组中第一个项目的起始地址,它将返回vec [0] .operator&amp;()将返回的任何内容。大多数(如果不是全部的话),这不是你正在寻找的地址(绝地手波)。
这是一个很好的例子是ATL的CComPtr。它会重载operator&amp;(),因此将其存储在向量中可能会有问题。为了解决这个问题,ATL有一个CAdapt模板类,可用于在CComPtr上隐藏运算符&amp;()
答案 3 :(得分:1)
在C ++ 11之前std::array
我会说std::vector
是最常用的容器,而不是C风格的数组。 []
运算符通常意味着持续时间访问(这是std::vector
的全部内容),因此大多数编码人员通常会选择此样式来反映类似数组的访问和行为。
答案 4 :(得分:0)
data()已经成为std::string
的一部分了一段时间,所以你可能会对此进行阅读。我发现std::vector
中的data()实现是相似的。我偶尔会使用data()将std::string
视为原始字节数组。