如何修复无效比较器错误?
How do I fix an Invalid Comparator error?
MSVS 16.9.3
Win7-64
第二次执行传递给 <algorithm>
中提供的 C++ 排序函数的排序比较器时,我收到无效比较器错误。我不明白为什么会出现此错误!排序例程调用是:
sort(sorted.begin(), sorted.end(), remsort);
sorted
定义如下:
vector<ADI::RDA_Asset*>& sorted = *(new vector<ADI::RDA_Asset*>);
这些是我使用的 remsort
的三个版本:
版本 1:始终有效:
bool HOAReports::remsort(ADI::RDA_Asset* lhs, ADI::RDA_Asset* rhs) {
return (lhs->getRem() < rhs->getRem());
};
版本 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)
};
版本 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;
};
版本 2/3 具有相同的功能。在第一次和第二次调用 remsort
时,只有 ((lhs->getRem() < rhs->getRem()
) 被执行并且 return_value 为真。查看失败的断言,似乎在两次调用中都检查了断言,但在第二次调用中失败了。
失败的 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;
}
您的比较函数不满足 strict weak 排序要求。参见 C++ named requirements: Compare。
在你的具体情况下,你可以这样实现:
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();
}
或者更简单,使用std::tuple
or std::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()};
}
MSVS 16.9.3
Win7-64
第二次执行传递给 <algorithm>
中提供的 C++ 排序函数的排序比较器时,我收到无效比较器错误。我不明白为什么会出现此错误!排序例程调用是:
sort(sorted.begin(), sorted.end(), remsort);
sorted
定义如下:
vector<ADI::RDA_Asset*>& sorted = *(new vector<ADI::RDA_Asset*>);
这些是我使用的 remsort
的三个版本:
版本 1:始终有效:
bool HOAReports::remsort(ADI::RDA_Asset* lhs, ADI::RDA_Asset* rhs) {
return (lhs->getRem() < rhs->getRem());
};
版本 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)
};
版本 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;
};
版本 2/3 具有相同的功能。在第一次和第二次调用 remsort
时,只有 ((lhs->getRem() < rhs->getRem()
) 被执行并且 return_value 为真。查看失败的断言,似乎在两次调用中都检查了断言,但在第二次调用中失败了。
失败的 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;
}
您的比较函数不满足 strict weak 排序要求。参见 C++ named requirements: Compare。
在你的具体情况下,你可以这样实现:
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();
}
或者更简单,使用std::tuple
or std::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()};
}