2011-10-11 24 views
5

Nella mia applicazione ho bisogno di memorizzare una piccola raccolta di dati temporanei. In questi dati temporanei voglio memorizzare un riferimento ad un'altra classe e dato che non può essere un nullptr, io uso un riferimento.Cancellare uno std :: vector richiede un operatore di assegnazione. Perché?

Usa un vettore per memorizzare i dati (non ho troppi dati, quindi il vettore va bene).

Il riempimento del vettore e il suo iterazione funziona correttamente, ma la risoluzione del vettore sembra dare problemi.

Questo è un codice semplificato che mostra il 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(); 
} 

Tutto compila e funziona perfettamente tranne l'ultima dichiarazione. Cancellazione del vettore dà questo messaggio di errore (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 
     ] 

Il motivo sembra essere che l'attuazione di std :: vector :: chiamate chiare std :: vector :: erase, che chiama il metodo _move , che sembra aver bisogno dell'operatore di assegnazione.

Perché non è possibile il metodo chiaro semplicemente:

  • chiamata il distruttore per tutti gli elementi nel vettore
  • impostare la dimensione vettore a zero

La cosa divertente è che quando ho usa std :: list invece di std :: vector, il codice viene compilato correttamente.

Perché è questo?

Anche altri compilatori hanno questo problema?

+1

Come nota a margine, i riferimenti in C++ non possono essere nulli e non possono essere ri-posti. A meno che non desideriate entrambe le proprietà, non dovreste usarle. –

risposta

11

Qualsiasi classe inserita in un vettore richiede un operatore di assegnazione copia (o almeno un'assegnazione di spostamento operatore in C++ 11). È solo una questione di qualità quando si verifica l'errore.

2

Avete effettivamente commentato la chiamata clear() e provato a compilarlo? Sono abbastanza sicuro (e il mio compilatore è d'accordo con me) che il push_back sta causando questo (a causa della copia necessaria dei dati esistenti)

+0

Il messaggio di errore dice che è necessario in 'erase', che è probabilmente chiamato da' clear' ('clear = cancella (inizio, fine)'). Anche se probabilmente l'assegnazione non verrà utilizzata per cancellare tutto, la funzione deve ancora essere compilata. L'assegnazione è comunque un requisito per i container. - push_back, immagino, può essere implementato in termini di costruttore di copie. – visitor

+0

Quando si commenta la chiamata chiara, tutto funziona perfettamente. – Patrick

Problemi correlati