C++ 清除std::vector需要赋值运算符。为什么?
在我的应用程序中,我需要存储一小部分临时数据。在这个临时数据中,我想存储对另一个类的引用,因为它不能是null ptr,所以我使用了一个引用 就是使用一个向量来存储数据(我没有太多的数据,所以向量很好) 填充向量并在其上迭代工作正常,但清除向量似乎会带来问题 这是一些显示问题的简化代码:C++ 清除std::vector需要赋值运算符。为什么?,c++,stl,C++,Stl,在我的应用程序中,我需要存储一小部分临时数据。在这个临时数据中,我想存储对另一个类的引用,因为它不能是null ptr,所以我使用了一个引用 就是使用一个向量来存储数据(我没有太多的数据,所以向量很好) 填充向量并在其上迭代工作正常,但清除向量似乎会带来问题 这是一些显示问题的简化代码: class Department { }; class Person { public: Person (const Department &dept)
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();
}
班级部门
{
};
班主任
{
公众:
人员(施工部和部门)
:m_dept(dept)
,m_工资(1000)
{}
私人:
施工部和机械部;
双薪;
};
#包括
int main()
{
性病媒人;
部门1;
部门2;
persons.push_back(Person(dept1));
人。推回(人(dept2));
人。清除();
}
除了最后一句话外,所有的东西都能完美地编译和工作。清除向量将显示此错误消息(Visual Studio 2010):
C:\DevStudio\Vs2010\VC\INCLUDE\xutility(2526):错误C2582:“operator=”函数在“Person”中不可用
C:\DevStudio\Vs2010\VC\INCLUDE\xutility(2547):请参阅正在编译的函数模板安装“\u OutIt std::\u Move(\u InIt,\u InIt,\u OutIt,std:\u Nonscalar\u ptr\u iterator\u tag)”
具有
[
_OutIt=人*,
_InIt=个人*
]
C:\DevStudio\Vs2010\VC\INCLUDE\vector(1207):请参阅正在编译的函数模板实例化“\u OutIt std::\u Move(\u InIt,\u InIt,\u OutIt)”的参考
具有
[
_OutIt=人*,
_InIt=个人*
]
C:\DevStudio\Vs2010\VC\INCLUDE\vector(1190):编译类模板成员函数“std::\u vector\u iterator std::vector::erase(std:\u vector\u const\u iterator,std:\u vector\u const\u iterator)”时
具有
[
_Myvec=std::\u Vector\u val,
_Ty=人
]
cpp(21):请参阅对正在编译的类模板实例化“std::vector”的引用
具有
[
_Ty=人
]
原因似乎是std::vector::clear的实现调用std::vector::erase,后者调用_Move方法,该方法似乎需要赋值运算符
为什么clear方法不能简单地:
- 为向量中的所有元素调用析构函数
- 将向量大小设置为零
其他编译器也有这个问题吗?您是否确实注释掉了clear()调用,并尝试编译它?我非常确定(我的编译器也同意我的观点)推回导致了这一点(由于需要复制现有数据)放入向量中的任何类都需要一个复制赋值操作符(或者至少是C++11中的移动赋值操作符)。当您真正获得错误时,这只是一个实现问题的质量。作为一个旁注,C++中的引用不能为空,不能重新定位。除非您想要这两个属性,否则不应该使用它们。错误消息说在
擦除中需要它,这可能是从清除调用的(清除=擦除(开始,结束)
)。即使赋值可能不会用于擦除所有内容,函数仍然需要编译。无论如何,可转让性是一项容器要求。-我想,push_back可以用拷贝构造函数实现。
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
]