Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vector preallocation does not work properly

Tags:

c++

vector

i have some trobles with the following code:

#include <iostream>
#incldue <vector>

template <typename ElemType>
class A{
private:

  std::vector<ElemType> data;

public:
  A() {};

  A(int capacity) {
    data.reserve(capacity);
  }

  int GetCapacity() {
    return data.capacity();
  }
};

int main() {
  A<int> a;
  a = A<int>(5);
  std::cout << a.GetCapacity() << std::endl; 
} 

The output is 0. What can be the problem?

like image 444
Pehat Avatar asked Dec 09 '22 04:12

Pehat


2 Answers

The copy-constructor and assignment operator of std::vector<T> are not required to copy the capacity of the vector, only the elements. Because the line a = A<int>(5) indirectly invokes the assignment operator (after creating a temporary), the vector in a does not have a capacity.

Try changing the first two lines of main to just A<int> a(5) and see what the results are.

If you absolutely need the capability to transfer the capacity from one instance to another, you need to define the assignment and copy-constructor of A to both copy the data and assign the capacity.

like image 77
Dave S Avatar answered Dec 14 '22 22:12

Dave S


Because you have not implemented the copy-assignment of A, preserving the capacity of the vector. The compiler generated copy-assignment of A, does ensure the only copying of elements of the vector. The vector's copy-constructor (and copy-assignment) is not required to preserve the capacity of the source vector object. It copies the elements, preserving the size of the vector.

That means, if you define the copy-assignment of A as:

 A& operator = (const A & a) 
 {
    data = a.data;
 }

It would still print 0.

The behaviour you want can be achieved by implementing the copy-assignment as:

 A& operator = (const A & a) 
 {
    data.reserve(a.capacity());
    data.insert(data.end(), a.begin(), a.end());
 }

Note that .insert() only copies the element, because of which .size() changes, but .capacity remains unchanged. That is why you need to explicitly call .reserve().

like image 26
Nawaz Avatar answered Dec 14 '22 23:12

Nawaz