【问题标题】:construct std::vector<int> with initial size without setting them to 0构造具有初始大小的 std::vector<int> 而不将它们设置为 0
【发布时间】:2021-12-30 09:46:36
【问题描述】:

这个

#include <fmt/core.h>
#include <vector>

int main() {
    std::vector<int> a(5);
    // a.resize(5) has the same effect

    fmt::print("{}\n", a.size());
    a.push_back(2);
    fmt::print("{}\n", a.size());

    return 0;
}

将输出:
5
6

我想给向量一个初始大小,但是当使用 int 向量这样做时,所有这些值都将设置为 0,我只是希望它们什么都不是,所以当我 push_back() 到向量,它不会调整大小,在那些无用的零之后添加元素。

【问题讨论】:

标签: c++ vector


【解决方案1】:

您需要使用reserve 函数而不是resize

#include <fmt/core.h>
#include <vector>


int main()
{
    std::vector<int> a; // construct the vector using the fefault ctor
    a.reserve( 5 ) // now a has a capacity of 5 but no elements have been initialized

    fmt::print( "Capacity: {} --- Size: {}\n", a.capacity(), a.size() );
    a.push_back( 83 );
    fmt::print( "Capacity: {} --- Size: {}\n", a.capacity(), a.size() );

    return 0;
}

使用resize(size_t n) 会将容量和大小都设置为n,但使用capacity(size_t n) 不会改变向量的大小,但它可能会增加已分配的大小空间。

另外,请注意capacity(size_t n) 可以降低容量。为此,您需要根据自己的需要使用resize(size_t n)shrink_to_fit(size_t n)

【讨论】:

    【解决方案2】:

    您正在构造 vector,其中 size 为 5 个 ints,它们的默认值都将是 0(您可以在构造函数)。然后您将第 6 个int 推入向量,增大其大小。这就是为什么你会得到你所看到的结果。

    您所要求的需要设置向量的 容量(它可以物理容纳多少项目)而不是它的 大小(有多少项目在 容量)。但是,没有办法在构造过程中设置容量,同时保持size为0。你必须在构造后显式调用vector::reserve()方法,例如:

    #include <fmt/core.h>
    #include <vector>
    
    int main() {
        std::vector<int> a;
        a.reserve(5);
    
        fmt::print("{} {}\n", a.capacity(), a.size());
        a.push_back(2);
        fmt::print("{} {}\n", a.capacity(), a.size());
    
        return 0;
    }
    

    输出:

    5 0
    5 1
    

    vector 现在的初始容量为 5 ints,它不会重新分配其数组,直到推送会导致其新的 大小超过该容量

    【讨论】:

      【解决方案3】:

      只声明std::vector&lt;int&gt; a;,不带大小参数。

      C++ 没有提供构造具有给定容量的向量的方法(参见 Java)。

      考虑使用reserve 是一种过度优化,并让 C++ 标准库在需要时为您调整向量的大小。除非性能分析另有说明,否则信任默认行为不太可能产生可衡量的效果。

      【讨论】:

      • reserve 在某些情况下可以提供非优化优势,因为这意味着容量不会改变,除非您超过预留大小(或调用其他容量更改函数,如 shrink_to_fit);如果您保持在保留容量内,则不会使迭代器和引用无效,即使优化不是问题,这也可以带来实际好处。这不一定是过早的优化。
      • @ShadowRanger:我发现依赖向量而不调整大小的代码相当脆弱。我更喜欢使用std::array 来处理这些事情。
      • 是的,并不是说这是个好主意,只是说这是一个合理的用例。 std::array 不允许延迟初始化(并且缺少廉价的移动/交换语义),而 reserved std::vector 之前的可以这样做(并且具有廉价的移动/交换语义)。
      猜你喜欢
      • 2012-07-12
      • 1970-01-01
      • 2020-10-28
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 2019-05-18
      • 1970-01-01
      相关资源
      最近更新 更多