C ++:“无效比较器”断言

时间:2017-08-30 17:48:46

标签: c++ c++11 stl

以下是代码:

struct Payment
{
    Payment(time_t time, float money) : mTime(time), mMoney(money) {}
    bool operator==(const Payment& p) const // exact comparison
    {
        return mTime == p.mTime && mMoney == p.mMoney;
    }
    time_t  mTime;
    float   mMoney;
};

std::vector<Payment>    payments;

auto sortP = [](const Payment& p1, const Payment& p2) { return p1.mTime < p2.mTime || p1.mMoney <= p2.mMoney; };
std::sort(payments.begin(), payments.end(), sortP);

std::sort(并非总是如此,但有时候,当两个元素的mTime彼此靠近时)会在Visual Studio 2015中引发无效的比较器断言。代码有什么问题?
 enter image description here

3 个答案:

答案 0 :(得分:3)

问题在于sortP的实施。它不符合严格的弱订购标准。请阅读http://www.sgi.com/tech/stl/StrictWeakOrdering.html上的详细信息。

我建议进行以下更改:

auto sortP = [](const Payment& p1, const Payment& p2)
{
   // Order by mTime if they are not equal.
   if ( p1.mTime != p2.mTime)
   {
     return p1.mTime < p2.mTime;
   }

   // Otherwise, order by pMoney
   return ( p1.mMoney < p2.mMoney); // Use < not <=
};

您可以使用std::tie来简化实施。

auto sortP = [](const Payment& p1, const Payment& p2)
{
   return std::tie(p1.mTime, p1.mMoney) < std::tie(p2.mTime, p2.mMoney);
};

答案 1 :(得分:1)

|| p1.mMoney <= p2.mMoney应为|| ((p1.mTime == p2.mTime) && (p1.mMoney < p2.mMoney))否则当p1.mTime大于p2.mTimep1.mMoney小于p2.Money时,对比情况会出错。确保此类多字段比较器满足严格的弱排序要求的良好做法是为所有可能的lt / gt字段组合编写测试。

答案 2 :(得分:1)

使用c++11比较器lambda应如下所示:

#include <tuple>
...
auto sortP = [](const Payment& p1, const Payment& p2) 
{ 
     return std::tie(p1.mTime, p1.mMoney) < std::tie(p2.mTime, p2.mMoney);
};