【问题标题】:std::vector: vec.data() or &vec[0]std::vector: vec.data() 或 &vec[0]
【发布时间】:2012-05-31 04:34:47
【问题描述】:

当您想以 C 数组的形式访问 std::vector 时,您可以从至少四种不同的方式中进行选择,如下例所示:

#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 */
  }
}

我在大多数情况下找到的是&amp;vec[0]。我认为它是最不优雅的,所以......为什么它是最常用的?是更高效还是更兼容?我找不到很多关于 data() 的文档。

【问题讨论】:

  • data() 可能被认为是不兼容的,因为它是 C++11(这解释了稀缺的文档,因为主要的文档来源刚刚赶上新功能) ,虽然时间肯定会让这种不兼容消失,然后这是明确的路要走。

标签: c++ arrays vector


【解决方案1】:

data() 对 C++11 来说是全新的,这就是你不经常看到它的原因。我从未想过使用&amp;vec.front() 的想法,可能是因为我使用operator[]front() 更频繁(几乎从不)。我想其他人也一样。

【讨论】:

  • @MooingDuck:仅适用于 const 向量,I think。我现在就测试一下。
  • @MooingDuck 不。添加它是为了让人们不必写信:v.empty()?NULL:&amp;v[0]
  • @MooingDuck 我的示例编译并运行,你可以看到 data() 返回一个非 const 指针。
  • 所以data() 不兼容旧的C++?
  • data() 一段时间以来一直是 libstdc++ 中向量的非标准扩展。现在它是 C++11 标准的一部分
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 2018-06-16
          • 1970-01-01
          • 2021-11-07
          • 1970-01-01
          • 2022-08-07
          • 2022-01-20
          • 2020-09-25
          • 1970-01-01
          • 2015-01-04
          相关资源
          最近更新 更多