Для очистки std :: vector требуется оператор присваивания. Почему?

В моем приложении мне нужно хранить небольшую коллекцию временных данных. В этих временных данных я хочу сохранить ссылку на другой класс, и, поскольку это не может быть nullptr, я использую ссылку.

Используется вектор для хранения данных (у меня не так много данных, поэтому вектор в порядке).

Заполнение вектора и итерация по нему работают нормально, но очистка вектора, похоже, вызывает проблемы.

Это упрощенный код, показывающий проблему:

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();
}

Все компилируется и работает отлично, ЗА ИСКЛЮЧЕНИЕМ последнего оператора. Очистка вектора дает следующее сообщение об ошибке (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
        ]

Причина, по-видимому, в том, что реализация std :: vector :: clear вызывает std :: vector :: erase, который вызывает метод _Move, который, похоже, нужен оператор присваивания.

Почему метод clear не может просто:

  • вызвать деструктор для всех элементов в векторе
  • установить размер вектора на ноль

Забавно то, что когда я использую std :: list вместо std :: vector, код компилируется правильно.

Почему это?

Есть ли эта проблема и в других компиляторах?

5
задан Patrick 11 October 2011 в 13:02
поделиться