Для очистки std :: vector требуется оператор присваивания. Зачем? - PullRequest
5 голосов
/ 11 октября 2011

В моем приложении мне нужно хранить небольшую коллекцию временных данных.В этих временных данных я хочу сохранить ссылку на другой класс, и поскольку это не может быть 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, код компилируется правильно.

Почему это так?

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

Ответы [ 2 ]

11 голосов
/ 11 октября 2011

Любой класс, помещенный в вектор, требует оператора присваивания копии (или, по крайней мере, оператора присваивания перемещения в C ++ 11). Это просто проблема качества реализации, когда вы на самом деле получаете ошибку.

2 голосов
/ 11 октября 2011

Вы на самом деле закомментировали вызов clear () и пытались его скомпилировать? Я почти уверен (и мой компилятор согласен со мной), что push_back вызывает это (из-за необходимого копирования существующих данных)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...