std :: sort将元素比较为null

时间:2014-02-18 01:38:36

标签: c++ algorithm sorting c++11

我有以下排序算法,它对std::vector个唯一armor_set指针进行排序。通过我的排序算法的某些属性,它会窒息并运行到未定义的行为,最终将有效的lhsrhs进行比较nullptr

尽管多次移动算法,但我一直无法辨别问题。我觉得我错过了一些关于这个std::sort算法如何工作的简单规则。

任何帮助都将不胜感激。

std::vector<armor_set*> armor_sets;

//insertion of unique armor sets here

std::sort(armor_sets.begin(), armor_sets.end(), [](armor_set* lhs, armor_set* rhs)
{
    auto lhs_collectible_count = collectible_mgr::get().count(lhs->needed_collectible);
    auto rhs_collectible_count = collectible_mgr::get().count(rhs->needed_collectible);

    if(lhs_collectible_count > 0 && rhs_collectible_count == 0)
    {
        return true;
    }
    else if(lhs_collectible_count == rhs_collectible_count)
    {
        return lhs->sort_index > rhs->sort_index;
    }
    else
    {
        auto lhs_collectibles_needed_count = lhs_collectible_count - lhs->collectibles_needed;
        auto rhs_collectibles_needed_count = rhs_collectible_count - rhs->collectibles_needed;

        return lhs_collectibles_needed_count > rhs_collectibles_needed_count;
    }
});

3 个答案:

答案 0 :(得分:10)

比较函数必须遵循严格弱序。

例如,如果我是sort函数,我会给你两个armor_set指针,问你“哪一个先来?”并返回一个表示哪个值最先出现的真/假值。然后我给你相同的两个armor_set指针,但这次,改变项目的顺序。我问你同样的问题“哪个先来?”。然后返回相同的true / false值。猜猜是什么 - 你失败了。

简而言之,这违反了严格的弱序。无法a < b,同时b < a。看看你有点复杂的比较函数,我的猜测是你违反了这条规则。

如果您正在使用Visual Studio,则调试运行时会对此类订单违规进行精确检查。比较函数被调用两次,第一次用A,B顺序,第二次用B,A顺序。比较每个调用的返回值,如果存在违规,则会发生assert()。

答案 1 :(得分:2)

比较操作(lambada)是问题所在。 sort中的运算符应确保定义的顺序是严格的弱顺序。即

1)For all x, it is not the case that x < x (irreflexivity).
2)For all x, y, if x < y then it is not the case that y < x (asymmetry).
3)For all x, y, and z, if x < y and y < z then x < z (transitivity).
4)For all x, y, and z, if x is incomparable with y, and y is incomparable with z, 
    then x is incomparable with z (transitivity of incomparability).

你的功能似乎很想念它。例如:

armor_set* lhs{
 lhs->needed_collectible=0;
 ....
}

armor_set* rhs{
 lhs->needed_collectible=1;
 ....
}

当您致电compare(lhr, rhs)时,它可能会返回truefalse取决于其他值。在您致电compare(rhs, lhs)时,请注意订单不同,它将始终返回truecompare(a,b)compare(b,a)都不允许返回true,这违反了严格弱顺序的属性。

答案 2 :(得分:1)

特定的失败是缺失的

if(lhs_collectible_count == 0 && rhs_collectible_count > 0)
{
    return false ;
}

应该是第二次或第三次测试。