Ошибка: передача x в качестве аргумента «this» из x отбрасывает квалификаторы - PullRequest
2 голосов
/ 01 июля 2019

Я пишу 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 ++.Поэтому, если это плохая практика для приведения объекта в соответствие с установленными требованиями, не стесняйтесь сообщить мне.

Ответы [ 3 ]

2 голосов
/ 01 июля 2019

Объекты Heart хранятся в std :: set.По этой причине я реализую операторы =, <и>.

Можно определить столько операторов, сколько вам нужно (больше операторов дают вашему классу большую гибкость).Однако использование std::set оправдывает только operator<;набор по умолчанию не использует "больше чем" или "равно" (что, по-видимому, означает то, что, как вы думали, будет означать один знак равенства).

При определении этих функций вы можете использовать только constчлены.Я пытался это сделать, но все равно получаю сообщение об ошибке: «1010 *

* 1012». Подумайте немного о том, что вы делаете.Вы хотите иметь возможность сравнивать два объекта, используя синтаксис, такой как A < B.Как вы заявили, они должны считаться постоянными operator<.Акцент на "эти" .Есть два объекта.Должны быть две const квалификации.Давайте посмотрим на объявление оператора, упомянутое в сообщении об ошибке:

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

Сколько раз в этом объявлении появляется "const"?Только однажды!Вам нужен еще один "const".Куда это должно идти?Сообщение об ошибке снова приходит на помощь: оно жалуется на аргумент this.Независимо от того, считается ли *this константой, определяется наличием или отсутствием ключевого слова const после списка параметров :

bool HeartbeatManager::Heart::operator<(const HeartbeatManager::Heart&) const
1 голос
/ 01 июля 2019

Вы принимаете константное значение lvalue до Heart. Означает, что функция не изменяет переданный экземпляр. Следовательно, все они должны быть const квалифицированными .

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);
}
1 голос
/ 01 июля 2019

Вы хотите разрешить вызов операторов сравнения для объекта const, поэтому замените

bool operator < (const Heart &o) {

на

bool operator < (const Heart &o) const {

и т. Д.

Также обратите внимание, что вы реализовали operator = () вместо operator == ()

...