2017-08-30 137 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); 
};