【问题标题】:Do not allow additon of more elements into a vector不允许将更多元素添加到向量中
【发布时间】:2019-04-01 09:10:19
【问题描述】:

我需要在std::vector 中保留 x 个元素,比如 10。然后我需要在其中写入一些 y 个值,比如 5(大部分时间 y

示例: 假设我分配了 10 个元素

std::vector<int> v(10);

但我只填充了其中的 7 个元素

for (unsigned i = 0; i<7; i++)
  v[i] = i;

我如何判断 7 个元素已被填充,而我还有 3 个可用?

我试过跑步 v.size()v.capacity() 但都返回 10。

【问题讨论】:

  • 考虑使用std::vector::reservestd::vector::push_back 方法。
  • 但我只填充了其中的 7 个元素 -- 你对“填充”的定义是什么?您声明了一个包含 10 个元素的向量,全部初始化为 0。如果您想要一个只有 7 个项目的向量,则创建一个只有 7 个项目的向量。
  • @PaulMcKenzie 我的动机是为最大数量的元素保留一些空间。元素的实际数量可以小于最大值,但永远不会更多。当我保留 10 个元素时,我不一定关心它们是否被初始化为 0,但是一旦我开始插入元素,我想知道我插入了多少。
  • 您没有在示例中进行任何插入。这些“插入”已经在构造函数中完成。你构造一个包含 10 个元素的向量,你得到 10 个元素,所以v.size() 当然返回 10。也许你对向量是什么的想法似乎有点缺陷。
  • 但我只填写了其中的 7 个元素 不。您修改其中 7 个元素。 = 在这里代表分配。赋值不会创建、分配、填充……它的左侧。它为已经存在的事物赋予了新的价值。

标签: c++ stl c++14 stdvector


【解决方案1】:

你的意思是这样的吗?

std::vector<int> a; // dont allocate anything

// allocate memory for 10 elements, 
// but dont actually create them. a.size() is still 0.
a.reserve(10); 

for(std::size_t i = 0; i < 7; ++i) {
    // copy i to a new element at the back 
    // of the vector. This will never reallocate 
    // memory, as long as at most 10 elements 
    // are pushed:
    a.push_back(i); 
}
// a.size() is now 7

【讨论】:

    【解决方案2】:

    编辑:我添加了一个使用std::unique_ptr的方法。


    如果您可以使用 C++17,那么将v 的元素替换为std::optional&lt;int&gt; 怎么样?

    #include <iostream>
    #include <optional>
    #include <vector>
    #include <algorithm>
    
    int main()
    {
        std::vector<std::optional<int>> v(10);
    
        for (std::size_t i = 0; i<7; ++i){
            v[i] = i;
        }
    
        std::cout 
            << (v.size() - std::count(v.cbegin(), v.cend(), std::nullopt))
            << " elements have been filled and I still have "
            << std::count(v.cbegin(), v.cend(), std::nullopt) 
            << " available."
            << std::endl << std::endl;
    
        for(const auto v_i : v)
        {
            if(v_i.has_value()){        
                std::cout << v_i.value() << " ";
            }
        }
    
        return 0;
    }
    

    但如果您受到旧版本的限制,我认为std::unique_ptr 将是一个解决方案。 DEMO:

    #include <iostream>
    #include <memory>
    #include <vector>
    #include <algorithm>
    
    int main()
    {
        std::vector<std::unique_ptr<int>> v(10);
    
        for (std::size_t i = 0; i<7; ++i){
            v[i] = std::make_unique<int>(i);
        }
    
        std::cout 
            << (v.size() - std::count(v.cbegin(), v.cend(), nullptr))
            << " elements have been filled and I still have "
            << std::count(v.cbegin(), v.cend(), nullptr) 
            << " available."
            << std::endl << std::endl;
    
        for(const auto& v_i : v)
        {
            if(v_i){        
                std::cout << *v_i << " ";
            }
        }
    
        return 0;
    }
    

    最后,我找到了类似的方法here

    【讨论】:

    • 我真的很喜欢这个解决方案,但有一个警告,我忘了提及。我受 C++14 的限制
    • 谢谢。这是我的荣幸。哦,我懂。我会考虑的。
    • @flashburn 虽然我不知道在这种情况下是否首选它,但我使用std::unique_ptr 添加了另一个解决方案并引用了类似方法。
    • boost::optional 在 C++14 中可用。
    【解决方案3】:

    我需要在std::vector 中保留 x 个元素,比如 10 个。

    std::vector 有一个 reserve() 方法用于此目的。

    然后我需要在其中写入一些 y 个值,比如 5(大部分时间 y

    向量的capacity() 是已分配的元素总数,而其size() 是已分配的已填充值的元素数。因此,capacity() - size() 是已分配但未分配的可用元素数。

    我尝试运行 v.size()v.capacity() 但都返回 10。

    这是因为您正在调用vector 构造函数,该构造函数同时分配和填充元素。您正在创建一个名为 vvector,其中有 10 个元素填充为 0。这就是为什么 size()capacity() 都是 10。没有一个构造函数会做你想要的。您需要使用默认构造函数,然后单独调用reserve(),例如:

    std::vector<int> v;
    v.reserve(10); // capacity = 10
    
    for (int i = 0; i < 7; ++i)
        v.push_back(i);
    
    size_t filled = v.size(); // size = 7
    size_t available = v.capacity() - v.size(); // available = 3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-18
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多