34

当您想将 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().

4

5 回答 5

23

data()对 C++11 来说是全新的,这就是为什么你不经常看到它的原因。我从来没有想过使用这个想法&vec.front(),可能是因为我使用operator[]的频率比front()(几乎从来没有)多很多。我想其他人也一样。

于 2012-05-24T15:05:53.107 回答
21

如果您使用的是 C++11,那么 usingdata()绝对是更可取的。特别是,如果向量为空,则使用其他两个选项中的任何一个都会产生未定义的行为!如果您没有使用 C++11,并且向量可能为空,请务必检查该条件。

于 2012-05-24T15:10:42.837 回答
6

使用 &vec[0] 是最常见的,但我同意,它看起来有点奇怪。未来要记住一件事。如果您的向量恰好是其类重载运算符 &() 的对象的向量,请意识到如果您调用 &vec[0],这将导致奇怪的行为。

这不会获得内部连续对象数组中第一项的起始地址,它将返回 vec[0].operator&() 将返回的任何内容。大多数情况下,即使不是所有时间,这都不是您要寻找的地址(绝地挥手)。

ATL 的 CComPtr 就是一个很好的例子。它使 operator&() 重载,因此将其存储在向量中可能会出现问题。为了解决这个问题,ATL 有一个 CAdapt 模板类,可以用来隐藏 CComPtr 上的 operator&()

于 2012-05-24T18:17:03.693 回答
1

在 C++11 之前std::array,我会说这std::vector是最常用的容器,而不是 C 样式的数组。[]运算符通常意味着恒定时间访问(这就是全部std::vector内容),因此大多数编码人员通常选择这种样式来反映类似数组的访问和行为。

于 2012-05-24T15:11:23.003 回答
1

data() 已经有std::string一段时间了,所以你可能会阅读它。我发现 data() 实现std::vector是相似的。我偶尔使用 data() 将 astd::string视为原始字节数组。

于 2012-05-24T15:37:05.827 回答