简体   繁体   English

如何修复无效的比较器错误?

[英]How do I fix an Invalid Comparator error?

MSVS 16.9.3 MSVS 16.9.3

Win7-64 Win7-64

I get an invalid comparator error on the second execution of my sort comparator passed to the C++ Sort function provided in <algorithm> .在第二次执行传递给<algorithm>中提供的 C++ 排序 function 的排序比较器时,我得到一个无效的比较器错误。 I don't understand why I am getting this error: The sort routine call is:我不明白为什么会出现此错误:排序例程调用是:

sort(sorted.begin(), sorted.end(), remsort);

sorted is defined like this: sorted的定义如下:

vector<ADI::RDA_Asset*>& sorted = *(new vector<ADI::RDA_Asset*>);

These are the three versions of remsort that I used:这些是我使用的三个版本的remsort

Version 1: always works:版本 1:始终有效:

bool HOAReports::remsort(ADI::RDA_Asset* lhs, ADI::RDA_Asset* rhs) { 
   return (lhs->getRem() < rhs->getRem());
};

Version 2: works on the first call to remsort by the sort routine, fails on the second:版本 2:在排序例程第一次调用 remsort 时工作,第二次失败:

bool HOAReports::remsort(ADI::RDA_Asset* lhs, ADI::RDA_Asset* rhs) { 
   return (  (lhs->getRem() < rhs->getRem())
          || ((lhs->getCatName()).compare(rhs->getCatName()) < 0)
          || ((lhs->getRDAName()).compare(rhs->getRDAName()) < 0)
          };

Version 3: works on the first call to remsort by the sort routine, fails on the second:版本 3:在排序例程第一次调用 remsort 时工作,第二次调用失败:

bool HOAReports::remsort(ADI::RDA_Asset* lhs, ADI::RDA_Asset* rhs) {
   bool return_value = (  (lhs->getRem() < rhs->getRem())
                      || ((lhs->getCatName()).compare(rhs->getCatName()) < 0)
                      || ((lhs->getRDAName()).compare(rhs->getRDAName()) < 0)
                       ); 
   return return_value;
};

Version 2/3 have the same functionality.版本 2/3 具有相同的功能。 On the first and second call to remsort only ( (lhs->getRem() < rhs->getRem() ) is executed and the return_value is true. Looking at the failed assertion, it looks like the assertion is checked on both calls but fails on the second.在第一次和第二次调用remsort ,仅执行 ( (lhs->getRem() < rhs->getRem() ) 并且 return_value 为真。查看失败的断言,看起来断言在两个调用中都被检查,但是第二次失败。

The MSVS code which fails is:失败的 MSVS 代码是:

// FUNCTION TEMPLATE _Debug_lt_pred
template <class _Pr, class _Ty1, class _Ty2,
    enable_if_t<is_same_v<_Remove_cvref_t<_Ty1>, _Remove_cvref_t<_Ty2>>, int> = 0>
constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept(
    noexcept(_Pred(_Left, _Right)) && noexcept(_Pred(_Right, _Left))) {
    // test if _Pred(_Left, _Right) and _Pred is strict weak ordering, when the arguments are the cv-same-type
    const auto _Result = static_cast<bool>(_Pred(_Left, _Right));
    if (_Result) {
        _STL_VERIFY(!_Pred(_Right, _Left), "invalid comparator");
    }

    return _Result;
}

Your comparison function does not fulfill the strict weak ordering requirements.您的比较 function 不满足严格的弱排序要求。 See C++ named requirements: Compare .请参阅C++ 命名要求:比较

In your specific case, you could implement it like this:在您的特定情况下,您可以像这样实现它:

bool HOAReports::remsort(ADI::RDA_Asset* lhs, ADI::RDA_Asset* rhs) {
    if(lhs->getRem() < rhs->getRem()) return true;
    if(rhs->getRem() < lhs->getRem()) return false;

    // if we get here, lhs.getRem() == rhs.getRem()

    auto cmp = lhs->getCatName().compare(rhs->getCatName());
    if(cmp) return cmp < 0;

    // if we get here, lhs->getCatName() == rhs->getCatName()

    return lhs->getRDAName() < rhs->getRDAName();
}

Demo演示

Or simpler, use std::tuple or std::tie :或者更简单,使用std::tuplestd::tie

#include <tuple>

bool HOAReports::remsort(ADI::RDA_Asset* lhs, ADI::RDA_Asset* rhs) {
    return
        std::tuple{lhs->getRem(), lhs->getCatName(), lhs->getRDAName()}
        <
        std::tuple{rhs->getRem(), rhs->getCatName(), rhs->getRDAName()};
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM