Clearing an std::vector needs an assignment operator. Why?
在我的应用程序中,我需要存储一小部分临时数据集合。在这个临时数据中,我想存储对另一个类的引用,因为它不能是nullptr,所以我使用了一个引用。
使用向量来存储数据(我没有太多的数据,所以向量很好)。
填充向量并对其进行迭代可以很好地工作,但是清除向量似乎会带来问题。
这是一些显示问题的简化代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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,后者调用了移动方法,而移动方法似乎需要赋值运算符。
为什么不能简单的用清晰的方法:
- 调用向量中所有元素的析构函数
- 将矢量大小设置为零
有趣的是,当我使用std::list而不是std::vector时,代码会正确编译。
为什么会这样?
其他编译器也有这个问题吗?
放置在向量中的任何类都需要一个复制赋值操作符(或者至少C++中的一个移动赋值运算符)。当您实际得到错误时,这只是一个实现质量问题。
您是否对clear()调用进行了注释,并试图编译它?我非常肯定(而且我的编译器也同意我的观点),推回造成这种情况(由于需要复制现有数据)