2011-10-11 33 views
5

Trong ứng dụng của tôi, tôi cần lưu trữ một bộ sưu tập dữ liệu tạm thời. Trong dữ liệu tạm thời này, tôi muốn lưu trữ một tham chiếu đến một lớp khác và vì nó không thể là một nullptr, tôi sử dụng một tham chiếu.Xóa một std :: vector cần một toán tử gán. Tại sao?

Sử dụng vectơ để lưu trữ dữ liệu (Tôi không có quá nhiều dữ liệu để vectơ là tốt).

Làm đầy véc tơ và lặp lại qua nó hoạt động tốt, nhưng việc xóa véc tơ dường như gây ra sự cố.

Đây là một số mã đơn giản cho thấy vấn đề:

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

Tất cả mọi thứ biên dịch và hoạt động hoàn hảo TRỪ báo cáo kết quả cuối cùng. Thanh toán bù trừ các vector mang lại cho thông báo lỗi này (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 
     ] 

Lý do dường như là việc thực hiện các std :: vector :: cuộc gọi rõ ràng std :: vector :: erase, trong đó kêu gọi các phương pháp _Move , có vẻ như cần toán tử gán.

Tại sao có thể không phải là phương pháp rõ ràng đơn giản:

  • gọi destructor cho tất cả các yếu tố trong vector
  • thiết lập kích thước vector để zero

Điều buồn cười là khi tôi sử dụng std :: list thay vì std :: vector, mã biên dịch chính xác.

Tại sao điều này?

Các trình biên dịch khác cũng có vấn đề này không?

+1

Như một lưu ý phụ, các tham chiếu trong C++ không được rỗng và không thể được đặt lại. Trừ khi bạn muốn cả hai thuộc tính bạn không nên sử dụng chúng. –

Trả lời

11

Bất kỳ lớp nào được đặt trong vectơ đều yêu cầu một toán tử gán bản sao (hoặc ít nhất là một nhiệm vụ di chuyển toán tử trong C++ 11). Nó chỉ là một vấn đề chất lượng thực hiện khi bạn thực sự nhận được lỗi.

2

Bạn đã thực sự nhận xét cuộc gọi rõ ràng() và đã cố gắng biên dịch chưa? Tôi khá chắc chắn (và trình biên dịch của tôi đồng ý với tôi) rằng push_back đang gây ra điều này (do sự sao chép cần thiết của dữ liệu hiện có)

+0

Thông báo lỗi nói rằng nó là cần thiết trong 'xóa 'mà có khả năng được gọi là từ' clear' ('clear = erase (bắt đầu, kết thúc)'). Mặc dù chuyển nhượng có thể sẽ không được sử dụng để xóa mọi thứ, chức năng vẫn phải biên dịch. Khả năng gán là một yêu cầu vùng chứa. - push_back, tôi tưởng tượng, có thể được thực hiện trong điều khoản của các nhà xây dựng bản sao. – visitor

+0

Khi nhận xét cuộc gọi rõ ràng, mọi thứ hoạt động hoàn hảo. – Patrick

Các vấn đề liên quan