W mojej aplikacji muszę przechowywać niewielką kolekcję danych tymczasowych. W tych tymczasowych danych chcę zapisać odniesienie do innej klasy i ponieważ nie może to być nullptr, używam odwołania.Usuwanie std :: vector wymaga operatora przypisania. Czemu?
Używa wektora do przechowywania danych (nie mam zbyt dużo danych, więc wektor jest w porządku).
Wypełnianie wektora i powtarzanie go działa dobrze, ale czyszczenie wektora wydaje się stwarzać problemy.
To jest jakiś uproszczony kod pokazujący 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();
}
Wszystko kompiluje i działa doskonale z wyjątkiem ostatniego oświadczenia. Usuwanie wektor daje ten komunikat o błędzie (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
]
Powodem wydaje się, że realizacja std :: vector :: wyraźne rozmowy std :: vector :: erase, który wywołuje metodę _Move , który wydaje się potrzebować operatora przypisania.
Dlaczego nie można po prostu klarowny sposób:
- wywołanie destruktora dla wszystkich elementów w wektorze
- ustawić rozmiar wektora do zera
Najśmieszniejsze jest to, że kiedy użyj std :: list zamiast std :: vector, kod kompiluje się poprawnie.
Dlaczego tak jest?
Czy inne kompilatory również mają ten problem?
Uwaga: odniesienia w C++ nie mogą być puste i nie można ich ponownie wstawić. Jeśli nie chcesz obu właściwości, nie powinieneś ich używać. –