Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clearing an std::vector needs an assignment operator. Why?

Tags:

c++

stl

In my application I need to store a small collection of temporary data. In this temporary data I want to store a reference to another class and since it can't be a nullptr, I use a reference.

Is use a vector to store the data (I don't have too much data so vector is fine).

Filling the vector, and iterating over it works fine, but clearing the vector seems to give problems.

This is some simplified code showing the problem:

class Department
   {
   };

class Person
   {
   public:
      Person (const Department &dept)
      : m_dept(dept)
      , m_salary(1000)
      {}
   private:
      const Department &m_dept;
      double m_salary;
   };

#include <vector>

int main()
{
std::vector<Person> persons;

Department dept1;
Department dept2;

persons.push_back (Person(dept1));
persons.push_back (Person(dept2));

persons.clear();
}

Everything compiles and works perfectly EXCEPT the last statement. Clearing the vector gives this error message (Visual Studio 2010):

C:\DevStudio\Vs2010\VC\INCLUDE\xutility(2526) : error C2582: 'operator =' function is unavailable in 'Person'
        C:\DevStudio\Vs2010\VC\INCLUDE\xutility(2547) : see reference to function template  nstantiation '_OutIt std::_Move<_InIt,_OutIt>(_InIt,_InIt,_OutIt,std::_Nonscalar_ptr_iterator_tag)' being compiled
        with
        [
            _OutIt=Person *,
            _InIt=Person *
        ]
        C:\DevStudio\Vs2010\VC\INCLUDE\vector(1207) : see reference to function template instantiation '_OutIt std::_Move<Person*,Person*>(_InIt,_InIt,_OutIt)' being compiled
        with
        [
            _OutIt=Person *,
            _InIt=Person *
        ]
        C:\DevStudio\Vs2010\VC\INCLUDE\vector(1190) : while compiling class template member function 'std::_Vector_iterator<_Myvec> std::vector<_Ty>::erase(std::_Vector_const_iterator<_Myvec>,std::_Vector_const_iterator<_Myvec>)'
        with
        [
            _Myvec=std::_Vector_val<Person,std::allocator<Person>>,
            _Ty=Person
        ]
        test.cpp(21) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
        with
        [
            _Ty=Person
        ]

The reason seems to be that the implementation of std::vector::clear calls std::vector::erase, which calls the _Move method, which seems to need the assignment operator.

Why can't the clear method simply:

  • call the destructor for all elements in the vector
  • set the vector size to zero

The funny thing is that when I use std::list instead of std::vector, the code compiles correctly.

Why is this?

Do other compilers also have this problem?

like image 312
Patrick Avatar asked Oct 11 '11 13:10

Patrick


People also ask

What does clearing a vector do?

clear() removes all the elements from a vector container, thus making its size 0. All the elements of the vector are removed using clear() function.

What happens when a vector goes out of scope C++?

Once your stack-allocated Frame t_frame = Frame(frameName, v); objects go out of scope their destructors are called and will delete all the objects pointed by pointers stored in Frame::displays .

Does vector clear deallocate?

clear() don't release or reallocate allocated memory, they just resize vector to zero size, leaving capacity same.

What is an std::vector?

1) std::vector is a sequence container that encapsulates dynamic size arrays. 2) std::pmr::vector is an alias template that uses a polymorphic allocator. The elements are stored contiguously, which means that elements can be accessed not only through iterators, but also using offsets to regular pointers to elements.


2 Answers

Any class put in a vector requires a copy assignment operator (or at least a move assignment operator in C++11). It's just a quality of implementation issue when you actually get the error.

like image 109
Sebastian Redl Avatar answered Oct 04 '22 02:10

Sebastian Redl


Have you actually commented out the clear() call, and tried to compile it? I am pretty sure (and my compiler agrees with me) that the push_back is causing this (due to the needed copying of existing data)

like image 32
PlasmaHH Avatar answered Oct 04 '22 04:10

PlasmaHH