清除 std::vector 需要赋值运算符。为什么?

发布于 2024-12-09 05:57:23 字数 2225 浏览 0 评论 0原文

在我的应用程序中,我需要存储一小部分临时数据。在这个临时数据中,我想存储对另一个类的引用,并且由于它不能是 nullptr,所以我使用引用。

是使用向量来存储数据(我没有太多数据,所以向量就可以了)。

填充向量并对其进行迭代工作正常,但清除向量似乎会出现问题。

这是一些显示问题的简化代码:

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):

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,它调用了 _Move 方法,该方法似乎需要赋值操作员。

为什么不能简单地使用clear方法:

  • 为向量中的所有元素调用析构函数
  • 将向量大小设置为零

有趣的是,当我使用std::list而不是std::vector时,代码可以正确编译。

这是为什么呢?

其他编译器也有这个问题吗?

In my application I need to store a small collection of temporary data. In this temporary data I want to store a reference to another class and since it can't be a nullptr, I use a reference.

Is use a vector to store the data (I don't have too much data so vector is fine).

Filling the vector, and iterating over it works fine, but clearing the vector seems to give problems.

This is some simplified code showing the 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();
}

Everything compiles and works perfectly EXCEPT the last statement. Clearing the vector gives this error message (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
        ]

The reason seems to be that the implementation of std::vector::clear calls std::vector::erase, which calls the _Move method, which seems to need the assignment operator.

Why can't the clear method simply:

  • call the destructor for all elements in the vector
  • set the vector size to zero

The funny thing is that when I use std::list instead of std::vector, the code compiles correctly.

Why is this?

Do other compilers also have this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

初相遇 2024-12-16 05:57:23

放入向量中的任何类都需要复制赋值运算符(或者至少在 C++11 中需要移动赋值运算符)。当您实际遇到错误时,这只是实施质量问题。

Any class put in a vector requires a copy assignment operator (or at least a move assignment operator in C++11). It's just a quality of implementation issue when you actually get the error.

朱染 2024-12-16 05:57:23

您是否真的注释掉了clear()调用,并尝试编译它?我非常确定(并且我的编译器同意我的观点)push_back 导致了这种情况(由于需要复制现有数据)

Have you actually commented out the clear() call, and tried to compile it? I am pretty sure (and my compiler agrees with me) that the push_back is causing this (due to the needed copying of existing data)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文