2011-10-11 17 views
5

En mi aplicación, necesito almacenar una pequeña colección de datos temporales. En esta información temporal, quiero almacenar una referencia a otra clase y como no puede ser un nullptr, utilizo una referencia.Borrado de un estándar :: vector necesita un operador de asignación. ¿Por qué?

Es utilizar un vector para almacenar los datos (no tengo demasiados datos para que el vector esté bien).

Rellenar el vector e iterar sobre él funciona bien, pero borrar el vector parece dar problemas.

Esto es código simplificado que muestra el problema:

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

Todo compila y funciona perfectamente, excepto la última declaración. Borrado del vector da este mensaje de error (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 
     ] 

La razón parece ser que la aplicación de std :: vector :: llamadas claras std :: vector :: erase, que llama al método _Move , que parece necesitar el operador de asignación.

¿Por qué no puede el método claro simplemente:

  • llamada al destructor de todos los elementos en el vector
  • establecer el tamaño del vector a cero

Lo curioso es que cuando use std :: list en lugar de std :: vector, el código se compila correctamente.

¿Por qué es esto?

¿Tienen otros compiladores también este problema?

+1

Como nota al margen, las referencias en C++ no pueden ser nulas y no se pueden volver a colocar. A menos que desee ambas propiedades, no debería usarlas. –

Respuesta

11

Cualquier clase puesta en un vector requiere un operador de asignación de copia (o al menos una asignación de movimiento) operador en C++ 11). Es solo una cuestión de calidad de implementación cuando realmente obtienes el error.

2

¿Ha comentado la llamada a clear() y ha intentado compilarla? Estoy bastante seguro (y mi compilador está de acuerdo conmigo) de que push_back está causando esto (debido a la necesaria copia de datos existentes)

+0

El mensaje de error dice que es necesario en 'borrar', que probablemente se llame desde 'borrar' (' borrar = borrar (comenzar, finalizar) '). Aunque la asignación probablemente no se utilizará para borrar todo, la función aún tiene que compilarse. La asignación es un requisito de contenedor de todos modos. - push_back, me imagino, se puede implementar en términos del constructor de copia. – visitor

+0

Al comentar la llamada clara, todo funciona perfectamente. – Patrick

Cuestiones relacionadas