在不破坏元素的情况下调整std :: vector的大小

时间:2014-02-14 12:04:05

标签: c++ c++11 vector

我一直在使用相同的std::vector<int>,以便尽量避免分配deallocating。在几行中,我的代码如下:

std::vector<int> myVector;
myVector.reserve(4);

for (int i = 0; i < 100; ++i) {
    fillVector(myVector);
    //use of myVector
    //....
    myVector.resize(0);
}

在每次迭代中,myVector将填充最多4个元素。为了生成有效的代码,我想始终使用myVector。但是,在myVector.resize()中,myVector中的元素正在被销毁。我知道myVector.clear()会产生同样的效果。

我想如果我可以覆盖myVector中的现有元素,我可以节省一些时间。但是我认为std::vector无法做到这一点。

有没有办法做到这一点?创建一个覆盖元素的本土实现是否有意义?

5 个答案:

答案 0 :(得分:5)

您的代码已经有效(myVector.clear()的样式优于myVector.resize(0))。

'int析构函数'什么都不做 因此resize(0)只需将size设置为0,capacity不受影响。

答案 1 :(得分:4)

只是不要继续调整myVector的大小。相反,请使用4个元素(使用std::vector<int> myVector(4))对其进行初始化,然后仅指定元素(例如myVector[0] = 5)。

但是,如果它总是固定大小,那么您可能更喜欢使用std::array<int, 4>

答案 2 :(得分:4)

将矢量调整为0 will not reduce its capacity,并且由于您的元素类型为int,因此不会运行析构函数:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v{1,2,3};
    std::cout << v.capacity() << ' ';
    v.resize(0);
    std::cout << v.capacity() << '\n';
}

// Output: 3 3

因此,您的代码已经基本上以最佳方式执行;您可以进行的唯一进一步优化是避免重新调整完全,从而在std::vector内失去可能归结为if语句的内部“设置大小为0”和数据成员值更改。

答案 3 :(得分:0)

实际上你目前所拥有的是

for (int i = 0; i < 100; ++i) {
    myVector.reserve(4);
    //use of myVector
    //....
    myVector.resize(0);
}

我认为该代码没有任何意义。

当然最好使用myVector.clear()代替myVector.resize(0);

如果你总是在循环中完全覆盖向量的4个元素,那么你可以使用

std::vector<int> myVector( 4 );

而不是

std::vector<int> myVector;
myVector.reserve(4);

提供函数fillVector(myVector);使用下标运算符来访问向量的这4个元素而不是成员函数push_back

否则请尽早使用clear

答案 4 :(得分:0)

在这种情况下,

std :: vector不是解决方案。你不想重新调整/清除/(de)重新分配?不。

  1. fillVector()用每次迭代中已知的元素数填充'vector'。
  2. Vector在内部表示为T *类型的连续内存块。
  3. 您不希望每次都(de)分配内存。
  4. 确定。使用简单的struct:

    struct upTo4ElemVectorOfInts
    {
      int data[4];
      size_t elems_num;
    };
    

    修改fillVector()以保存其他信息:

    void fillVector(upTo4ElemVectorOfInts& vec)
    {
      //fill vec.data with values
      vec.elems_num = filled_num; //save how many values was filled in this iteration
    }
    

    以同样的方式使用它:

    upTo4ElemVectorOfInts myVector;
    
    for (int i = 0; i < 100; ++i)
    {
      fillVector(myVector);
      //use of myVector:
      //- myVector.data contains data (it's equivalent of std::vector<>::data())
      //- myVector.elems_num will tell you how many numbers you should care about
      //nothing needs to be resized/cleared
    }
    

    附加说明:

    如果您想要更通用的解决方案(对任何类型或尺寸进行操作),您当然可以使用模板:

    template <class T, size_t Size>
    struct upToSizeElemVectorOfTs
    {
      T data[Size];
      size_t elems_num;
    };
    

    并调整fillVector()以接受模板而不是已知类型。

    这个解决方案可能是最快的解决方案。你可以这样想:“嘿,如果我想填充100个元素?1000?10000?那么呢?10000-elem数组将消耗大量存储空间!”。 无论如何它会消耗。 Vector会自动调整大小,并且此reallocs不受您的控制,因此效率非常低。如果您的阵列相当小并且您可以预测所需的最大大小,请始终使用在本地堆栈上创建的固定大小的存储。它更快,更高效,更简单。当然,这对于1.000.000元素的数组不起作用(在这种情况下你会得到Stack Overflow。)