std :: sort给出了非常奇怪的结果

时间:2013-09-23 11:23:09

标签: c++ stl

我设法找到了一个可重复的例子,说明我在std::sort

看到的奇怪行为

我正在尝试对一对列表进行排序,它应该在第二个元素上排序。第二个元素的列表是[1 1 1 1 3 1 1 1 1 1 1 3 2 1 1 5 2 1 7 1]

以下是我的代码:

std::vector<pair<int, double> > pairs;
for (int i = 0; i < 4; i++) {
    pairs.push_back(pair<int, double>(1, 1));
}
pairs.push_back(pair<int, double>(1, 3));
for (int i = 0; i < 6; i++) {
    pairs.push_back(pair<int, double>(1, 1));
}
pairs.push_back(pair<int, double>(1, 3));
pairs.push_back(pair<int, double>(1, 2));
pairs.push_back(pair<int, double>(1, 1));
pairs.push_back(pair<int, double>(1, 1));
pairs.push_back(pair<int, double>(1, 5));
pairs.push_back(pair<int, double>(1, 2));
pairs.push_back(pair<int, double>(1, 1));
pairs.push_back(pair<int, double>(1, 7));
pairs.push_back(pair<int, double>(1, 1));

,排序功能是:

template<typename T>
struct descending_sort {
    bool operator()(pair<T, double> const & a, pair<T, double> const & b) const {
        cout << "sorting (" << a.second << " , " << b.second << ")" << std::endl;
        return a.second >= b.second;
    }
};

descending_sort < int > d = descending_sort<int>();
std::sort(pairs.begin(), pairs.end(), d);

这会产生正确的结果,但是当我仔细检查每一步的sort函数输出(我打印到控制台)时,我会得到一些非常有趣的输出。

可以找到整个输出here但是有一些奇怪的行(即链接页面中的第46行),其中包含:

sorting (0 , 1)

但是0没有出现在输入列表中。这是为什么?

2 个答案:

答案 0 :(得分:15)

您的代码会导致未定义的行为,因为std::sort()需要严格的弱排序,<>提供,但>=不提供,因为它违反了反对称的要求

关于strict weak ordering,它还包括以下属性

(1)反对称

That for operator <: If x < y is true, then y < x is false.
That for a predicate op(): If op(x,y) is true, then op(y,x) is false.

(2)传递

对于运算符&lt ;:如果x&lt; y是真的,y&lt; z为真,则x < z是真的。    对于谓词op():如果op(x,y)为真且op(y,z)为真,则op(x,z) 是的。

(3) irreflexive

That for operator <: x < x is always false.
That for a predicate op(): op(x,x) is always false.

(4)等价的传递性,大​​致意味着:如果a等于b而b等于c,则a等于c。

§25.4.4

  

对于所有采用比较的算法,有一个版本使用运算符&lt;代替。也就是说,1comp(* i,* j)!= false1默认为* i&lt; * j!= false。 对于25.4.3中描述的算法以外的算法无法正常工作,comp必须对值进行严格的弱排序。

详细了解strict weak ordering

答案 1 :(得分:3)

在C ++中,“compare”谓词必须是strict weak ordering。例如,案例descending_sort( X, X )(两对完全相同)应始终返回false

此外,在reference上,有人说:

  

comp - 比较函数,如果第一个参数 less ,则返回true。

对你而言,这意味着在descending_sort

return a.second >= b.second;

应该是

return a.second > b.second;