Error: passing x as 'this' argument of x discards qualifiers

Error: passing x as 'this' argument of x discards qualifiers

我正在为我的应用程序编写 HeartbeatManager(在 visual studio 中)。 1个心跳的数据存储在一个Heart对象中。 Heart 个对象存储在 std::set 中。为此,我正在实施 operator=operator<operator> 重载。

定义这些函数时,您只能使用 const 成员。我尝试这样做,但仍然收到一条错误消息,提示我不是:

passing const HeartbeatManager::Heart' as 'this' argument of 'bool HeartbeatManager::Heart::operator<(const HeartbeatManager::Heart&)' 
discards qualifiers [-fpermissive]

这是代码。我看不到我在哪里使用非常数:

class HeartbeatManager
{
public:
    class Heart
    {
    public:
        Heart(const IPAddress _ip, const uint16_t _port, int _lifetime = 5000)
            : ip(_ip), port(_port), lifetime(_lifetime) {}

        const IPAddress ip;
        const uint16_t port;
        int lifetime;
        /**
        * Ages the Heart, returns whether it survived (lifetime after aging > 0)
        */
        bool age(int ms) 
        {
            this->lifetime -= ms;
            return 0 < this->lifetime;
        }

        // overloaded operators so heart struct can be sorted and used in map
        bool operator=(const Heart& o) {
            return ip == o.ip && port == o.port;
        }

        bool operator<(const Heart& o) {
            return (uint32_t)ip < (uint32_t)o.ip || (ip == o.ip && port < o.port);
        }

        bool operator>(const Heart& o) {
            return (uint32_t)ip > (uint32_t)o.ip || (ip == o.ip && port > o.port);
        }
    };
    void heartbeat(IPAddress ip, uint16_t port, int sec = 5000);
};

我是 C++ 的新手。因此,如果这是使对象符合设定要求的不良做法,请随时告诉我。

您想允许在 const 对象上调用比较运算符,因此替换

bool operator < (const Heart &o) {

bool operator < (const Heart &o) const {

等等。

另请注意,您实施的是 operator = () 而不是 operator == ()

您正在对 Heart 使用 const-qualified 左值引用。这意味着函数不会改变传递的实例。因此它们都应该是 const qualified.

bool operator==(const Heart& o) const
//          ^^^--> typo         ^^^^^
{
    return ip == o.ip && port == o.port;
}
bool operator<(const Heart& o) const
//                             ^^^^^
{
    return (uint32_t)ip < (uint32_t)o.ip || (ip == o.ip && port < o.port);
}
bool operator>(const Heart& o)  const
//                              ^^^^^
{
    return (uint32_t)ip > (uint32_t)o.ip || (ip == o.ip && port > o.port);
}

也就是说,您的 operator<operator> 可以使用 std::tie

提供的字典序比较来简化
bool operator< (const Heart& o) const
{
    return std::tie(ip, port) < std::tie(o.ip, o.port);
}
bool operator> (const Heart& o)  const
{
    return std::tie(o.ip, o.port) < std::tie(ip, port);
}

The Heart objects are stored in an std::set. For this reason I am implementing the =, < and > operators.

您可以定义任意数量的运算符(运算符越多,您的 class 就越灵活)。但是,使用 std::set 只能证明 operator<;默认集不使用 "greater than" 或 "equal to"(这大概是您认为单个等号的意思)。

When defining these functions you can only use const members. I tried to do this but still get an error saying I'm not:

花点时间想想你在做什么。您希望能够使用 A < B 等语法比较两个对象。如您所述,operator< 应将这些视为常量。强调"these"。有 两个 个对象。应该有两个const个资格。我们看一下报错信息中提到的运算符声明:

bool HeartbeatManager::Heart::operator<(const HeartbeatManager::Heart&)

const”在该声明中出现了多少次?只有一次!您需要另一个“const”。它应该去哪里?错误消息再次出现:它抱怨 this 参数。 *this 是否被认为是常量由 the presence or absence of the const keyword after the parameter list:

决定
bool HeartbeatManager::Heart::operator<(const HeartbeatManager::Heart&) const