【问题标题】:Compile Error with std::deque::erase with const members of the class使用类的 const 成员使用 std::deque::erase 编译错误
【发布时间】:2016-02-26 14:15:20
【问题描述】:

我在这里得到一个编译错误,我不知道代码有什么问题。我正在使用 g++ 4.9.2。

#include<iostream>
#include<deque>

using std::string;
using std::deque;

class Dummy {
public:
    virtual ~Dummy(){};
    Dummy():ID_("00") {};
private:

    const string ID_;
};

int main(){
    {
    deque <Dummy> waiter;
    waiter.push_back(Dummy());
    waiter.erase( waiter.begin() );
    }
    return 0;
}

编辑:我知道删除 const 会删除编译错误,但我不知道为什么。无论如何,我需要这个常量。

【问题讨论】:

  • 请添加错误信息。
  • 我不得不说,在编译了这个之后,gcc 4.9.2 的输出非常长而且毫无帮助。我不会在这里重复来咀嚼页面。

标签: c++ stddeque


【解决方案1】:

std::deque::erase 期望元素的类型应该是MoveAssignable:

类型要求

T 必须满足 MoveAssignable 的要求。

而Dummy 类有一个常量成员const string ID_;,这使得它不能被默认赋值运算符赋值。

您可以将ID_ 设为非常量成员,或者提供您自己的赋值运算符以使其可赋值。例如

Dummy& operator=(const Dummy&) { /* do nothing */ }

LIVE

【讨论】:

  • 这就是它的要点。删除擦除也可以解决编译错误。
  • 同意。我得到了相同的结果,但错过了 MoveAssignable 要求的相关性 - 很好发现!
  • @songyuanyao 你认为你的“可分配”解决方案是合法的吗?我认为它应该是 MoveAssignable 一定是有原因的......
  • @varantir 是方法的要求。想象一下,如果你删除了deque 中间的一个元素,它必须移动剩余的元素来填补空缺。这意味着它将调用赋值运算符来移动它们的位置。
  • @songyuanyao 但是如果我相应地修改移动可赋值运算符,我认为擦除元素时的移动将无法正常工作!
【解决方案2】:

您应该删除const 前缀,以便可以更改字符串:

string ID_;

或者将其更改为静态变量并像这样初始化它:

class Dummy {
public:
    virtual ~Dummy(){};
    Dummy() {};
private:

    static const string ID_;
};

const string Dummy::ID_ = "00";

你可以找到更多关于 const 字符串初始化的信息here。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-04
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多