【问题标题】:What is the difference between std::array and std::vector? When do you use one over other? [duplicate]std::array 和 std::vector 有什么区别?你什么时候使用一个而不是另一个? [复制]
【发布时间】:2011-10-01 18:09:20
【问题描述】:

std::arraystd::vector 有什么区别?你什么时候使用一个而不是另一个?

我一直使用并认为std:vector是一种使用C数组的C++方式,那么有什么区别呢?

【问题讨论】:

    标签: c++ arrays vector


    【解决方案1】:

    std::array 只是经典 C 数组的一个类版本。这意味着它的大小在编译时是固定的,它将被分配为单个块(例如,在堆栈上占用空间)。它的优点是性能稍好一些,因为对象和数组数据之间没有间接关系。

    std::vector 是一个包含指向堆的指针的小类。 (因此,当您分配 std::vector 时,它总是调用 new。)它们的访问速度稍慢,因为必须追逐这些指针才能到达数组数据......但作为交换,它们可以调整大小而且无论它们有多大,它们只占用微不足道的堆栈空间。

    [编辑]

    至于何时使用一个而不是另一个,老实说std::vector 几乎总是你想要的。在堆栈上创建大对象通常是不受欢迎的,额外的间接级别通常是无关紧要的。 (例如,如果您遍历所有元素,则额外的内存访问仅在循环开始时发生一次。)

    向量的元素保证是连续的,因此您可以将&vec[0] 传递给任何期望指向数组的指针的函数;例如,C 库例程。 (顺便说一句,std::vector<char> buf(8192); 是一种无需直接调用 new 即可为 read/write 或类似调用分配本地缓冲区的好方法。)

    也就是说,缺少这种额外的间接级别,加上编译时常量的大小,可以使 std::array 显着加快一个非常小的数组,该数组被创建/销毁/访问很多。

    所以我的建议是:使用std::vector,除非 (a) 您的分析器告诉您有问题并且 (b) 数组很小。

    【讨论】:

    • 等等,什么开销?两者都通过“指针”进行间接处理。 std::array 的“指针”只是伪装成 T arr[N];
    • @Xeo:那不是指针;它是一个数组。它实际上是inside对象;不是对象指向的。如果查看生成的汇编代码,您会发现访问向量元素比访问数组涉及更多的内存访问。 (尽管在实践中它通常是无关紧要的;例如,循环一个向量只在循环开始时执行一次额外的间接。)
    • @Xeo:不完全是:std::vector 的数据存储在单独分配的内存中。 std::array 的数据不是。 (当您需要时,cmets 的 -1 按钮在哪里?)
    • +1,但我会指出“面向对象”可能会产生误导……std::array 不必包含对象(std::vector 也不必包含对象)问题)。
    • @Caleb:这不是真的。 std::vectorstd::array 必须 使用对象类型。您不能拥有(例如)std::vector 的引用或 std::array 的函数。
    【解决方案2】:

    我将假设您知道 std::array 的大小在编译时是固定的,而 std::vector 的大小是可变的。另外,我假设您知道 std::array 不进行动态分配。所以相反,我会回答为什么你会使用 std::array 而不是 std::vector。

    你有没有发现自己这样做过:

    std::vector<SomeType> vecName(10);
    

    然后你从来没有真正增加 std::vector 的大小?如果是这样,那么 std::array 是一个不错的选择。

    但实际上,std::array(加上初始化列表)的存在使得 C 风格的数组几乎完全没有价值。它们通常不与 std::vectors 竞争;它们与 C 风格的数组竞争更多。

    可以将其视为 C++ 委员会尽最大努力消除 C 样式数组的几乎所有合法使用。

    【讨论】:

      【解决方案3】:

      std::array

      • 是一个聚合
      • 是固定大小的
      • 要求其 元素是默认可构造的(vs 复制 (C++03) 或移动 (C++0x) 可施工)
      • 是线性的 可交换(相对于恒定时间)
      • 可线性移动(相对于恒定时间)
      • 可能比std::vector少支付一个间接费用

      一个好的用例是在做“接近金属”的事情时,同时保持 C++ 的精妙之处并避免原始数组的所有坏事。

      【讨论】:

        【解决方案4】:

        使用 C 风格的 静态 数组而不是 std::vector 时的推理相同。为此,我请您联系here

        【讨论】:

        • 我不得不说,我认为我比任何一个都更喜欢我的答案。但也许我只是困了。
        • @Nemo:我同意你的回答更好,如果你能总结一下何时使用一个而不是另一个,那就完整了。
        【解决方案5】:

        std::array 具有固定(编译时)大小,而std::vector 可以增长。

        因此,std::array 就像使用 C 数组,而 std::vector 就像动态分配内存。

        【讨论】:

        • 这对于嵌入式世界来说非常重要。在我的环境中,我没有堆,并且不允许动态内存分配。我们只有堆栈。所以禁止使用向量。 std::array 对我们很好。谢谢。
        • @MehmetFide 我很好奇那是什么样的环境:)
        【解决方案6】:

        我使用的是我自己亲手编码的Array&lt;&gt; 模板类,与std::arraystd::vector 相比,它的API 更简单。例如:

        使用动态数组:

        Array<>  myDynamicArray; // Note array size is not given at compile time
        myDynamicArray.resize(N); // N is a run time value
        
        ...
        

        要使用静态数组,在编译时固定大小:

        Array<100> myFixedArry;
        

        我相信它的语法比std::arraystd::vector 更好。也非常高效。

        【讨论】:

        • 介意实际发布那个 Array 模板吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 1970-01-01
        • 1970-01-01
        • 2021-03-23
        • 1970-01-01
        • 2018-06-04
        相关资源
        最近更新 更多