«недопустимый компаратор»: ошибка при перегрузке оператора «<» - PullRequest
5 голосов
/ 20 июня 2019

У меня есть класс, который нужно отсортировать. Используя вектор этого класса, я получаю ошибку "недопустимый компаратор" при сортировке.

Я перегрузил оператор "<" в своем классе и <strong>следовал за строгим слабым порядком .

Как уже упоминалось в этом сообщении .

sort требует строгого слабого порядка. Ваш comparator не один. Среди прочего, для строгого слабого порядка, comp(x, x) должно быть false .

Это мой код:

bool outlierScore::operator<(const outlierScore& other) {
    if (score < other.score)
        return score < other.score;
    else if (coreDistance < other.coreDistance)
        return coreDistance < other.coreDistance;
    else if (id < other.id)
        return id < other.id;
    else
        return false;
}

это перегруженная операторная функция, которая, по сути, пытается отсортировать в порядке возрастания по значению выброса, с расстояниями до сердечника, используемыми для разрыва. связи между показателями выбросов и идентификаторы, используемые для разрыва связей между ядрами.

Stack Trace выявил ошибку, возникающую на этом этапе.

template <class _Pr, class _Ty1, class _Ty2>
constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) _NOEXCEPT_COND(
    noexcept(_Pred(_Left, _Right))
    && noexcept(_Pred(_Right, _Left))) { // test if _Pred(_Left, _Right) and _Pred is strict weak ordering
    const auto _Result = static_cast<bool>(_Pred(_Left, _Right));
    if (_Result) {
        _STL_VERIFY(!_Pred(_Right, _Left), "invalid comparator");
    }

    return _Result;
}

Я не могу найти проблему. Любая помощь будет великолепна.

Минимальный воспроизводимый пример :

class outlierScore
{
private:
    double coreDistance;
public:
    double score;
    int id;
}
vector <vector<double>> x = {
                {0,0.889528896739179,0.536626916823739},
                {1,1.30766765703343,0.684794721931497},
                {2,0.936505261432846,0.559870334496815}
            };
vector<outlierScore> test;
test.push_back(outlierScore(x[0][2], x[0][1], x[0][0]));
test.push_back(outlierScore(x[1][2], x[1][1], x[1][0]));
test.push_back(outlierScore(x[2][2], x[2][1], x[2][0]));

содержит объекты outlierScore, которые выглядят как {id, coreDistance, score}

Где выдает ошибку: sort(test.begin(), test.end());

Ответы [ 2 ]

10 голосов
/ 20 июня 2019

Кроме метода, отличного от const, этот оператор не удовлетворяет строгому слабому порядку.

bool outlierScore::operator<(const outlierScore& other) {
    if (score < other.score)
        return score < other.score;
    else if (coreDistance < other.coreDistance)
        return coreDistance < other.coreDistance;
    else if (id < other.id)
        return id < other.id;
    else
        return false;
}

Например, если все поля являются целыми числами.

a.score = 0 ; a.coreDistance = 1
b.score = 1 ; b.coreDistance = 0

Для этих значений следующее должно быть ложным, но возвращается true:

a < b && b < a

Вы также должны проверить равенство:

bool outlierScore::operator<(const outlierScore& other) {
    if (score != other.score)
        return score < other.score;
    else if (coreDistance != other.coreDistance)
        return coreDistance < other.coreDistance;
    else 
        return id < other.id;
}
10 голосов
/ 20 июня 2019

Ваша реализация неверна.

bool outlierScore::operator<(const outlierScore& other) const {
    return (score < other.score) ||
           (score == other.score && coreDistance < other.coreDistance) ||
           (score == other.score && coreDistance == other.coreDistance && id < other.id);
}

Или

bool outlierScore::operator<(const outlierScore& other) const {
    return std::tie(score, coreDistance, id) < std::tie(other.score, other.coreDistance, other.id);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...