Patrick
Patrick

Reputation: 23619

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

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:

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?

Upvotes: 5

Views: 1972

Answers (2)

PlasmaHH
PlasmaHH

Reputation: 16046

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)

Upvotes: 2

Sebastian Redl
Sebastian Redl

Reputation: 71959

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.

Upvotes: 11

Related Questions