2017-08-30 139 views
1

下面是代码:С++:“无效比较”断言

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

+1

'|| p1.mMoney <= p2.mMoney'应该是'|| ((p1.mTime == p2.mTime)&&(p1.mMoney VTT

+1

比较两个浮动并不是一个好主意,浮动并不完全代表,它们是近似值。您需要比较差异小于一些三角洲。按照同样的理由把钱存入浮动并不是一个好主意。 –

+0

@VTT:你说得对,这是解决方案。让它成为答案,我会接受。 – deko

回答

1

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

+5

好的做法是使用'std :: tie' – Slava

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); 
}; 
+3

使用'std :: tie'更简单 – Slava

+0

@Slava,当然。感谢提示。 –

1

使用c++11你比较拉姆达应该是这样的:

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