Vector preselection does not work properly

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 result is 0. What could be the problem?

+4
source share
3 answers

The copy-constructor operator and the std::vector<T> assignment do not need to copy the capacity of the vector, but only the elements. Since the string a = A<int>(5) indirectly calls the assignment operator (after creating the temporary one), the vector in a has no capacity.

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

If you absolutely need the ability to transfer capacity from one instance to another, you need to determine the purpose and copy constructor A to copy the data and the purpose of the capacity.

+11
source

Since you did not complete the assignment of copy A , preserving the bandwidth of the vector. The compiler generated copy assignment A , guarantees a single copy of the elements of the vector. A vector constructor-copier (and destination-copy) is not required to preserve the capacity of the original vector object. It copies elements while maintaining the size vector.

This means that if you define the copy destination A as:

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

It will print 0 anyway.

The behavior you want can be achieved by implementing the copy destination 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 due to which .size() changes, but .capacity remains unchanged. This is why you need to explicitly call .reserve() .

+2
source

This is because you assign a, the assignment will only copy values ​​and capacity.

if you want to build with installed capacity.

 A<int> a(5); 

If you need bandwidth for destination transfer, you will need to write your own assignment operator

 A& operator=(const A& a) { if(&a!=this) { data.assign(a.data); data.reserve(a.capacity); } return *this; } 
+1
source

Source: https://habr.com/ru/post/1385742/


All Articles