【问题标题】:C++: vector.erase instance of a class with const int gives "attempting to reference a deleted function" error C2280C++:带有 const int 的类的 vector.erase 实例给出“试图引用已删除的函数”错误 C2280
【发布时间】:2017-04-09 13:32:34
【问题描述】:

C++:带有 const int 的类的 vector.erase 实例给出“试图引用已删除的函数”错误 C2280

B 类有一个 const int 属性const_int。如果我创建一个包含 B 实例的向量,然后从该向量中删除一个元素 - 我会收到以下错误:

Error   C2280   'B &B::operator =(const B &)': attempting to reference a deleted function   VectorTest  c:\program files (x86)\microsoft visual studio\2017\prof\vc\tools\msvc\14.10.25017\include\xutility 2534    

如果我删除 const 关键字 - 错误就会消失。 如何在保持属性const_int 不变的同时修复它? 为什么会出现此错误,vector.erase() 是否试图从 B 类调用某个函数? 谢谢!

B.h

#pragma once
#include <iostream>
#include <vector>
using namespace std;

class B
{
private:
    const int const_int;
public:
    B(int const_int_input);
    ~B();
};

B.cpp

#include "B.h"

B::B(int const_int_input) : const_int(const_int_input)
{
}


B::~B()
{
}

源.cpp

#include "B.h"

int main() {
    vector<B> test;
    test.push_back(B(1));
    test.erase(test.begin());
    return 0;
}

【问题讨论】:

  • std::vector&lt;&gt;::erase 需要能够分配向量的元素以折叠空间(由擦除操作创建)。由于类B 包含一个常量,因此编译器会自动将赋值运算符声明为已删除,因为无法分配给常量值。请参阅类型要求 en.cppreference.com/w/cpp/container/vector/erase

标签: c++ class oop vector constants


【解决方案1】:

根据std::vector::erase 文档:

类型要求 - T 必须满足 MoveAssignable 的要求。

因此,为了使用std::vector::erase,您需要有一个移动赋值运算符 (T&amp; operator = (T&amp;&amp;)) 或一个复制赋值运算符 (T&amp; operator = (const T&amp;))。由于您提供了自己的构造函数,因此编译器没有生成任何赋值运算符。

这个要求背后的逻辑是向量试图用其余的变量来填补erase造成的空白。它试图将元素向右移动到已擦除的元素,以填补erase 造成的空洞。

由于您的班级有const int,这意味着您实际上并不希望分配您的对象,因为const_int 是.. const。您明确表示您不希望重新分配此变量。

在这种情况下,您可以创建一个指向 B 的指针数组:

std::vector<std::unique_ptr<B>> vector;
vector.emplace_back(std::make_unique<B>(1));
vector.erase(vector.begin());

另一种可能性是丢失const_int 上的const 并提供移动分配操作符。

【讨论】:

  • 天哪,我无法想象我花了多长时间才发现我班上的那个小 const var 是罪魁祸首。非常感谢您的解释!
猜你喜欢
  • 2014-09-15
  • 2014-02-19
  • 1970-01-01
  • 2014-01-10
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多