GCC的std :: sort与lambdas的不稳定行为

S. *_* K. 4 c++ lambda gcc stl c++11

使用GCC 6.1.0编译时,以下代码生成分段错误.奇怪的是,错误是一致的,但不会出现较小的尺寸或略微不同的比较表达式.你们有什么想法吗?

#include <vector>
#include <algorithm>
#include <iostream>
int main() {
    int n = 1000;   
    std::vector<std::pair<double, double>> vec;
    for(int i = 0; i < n; i++) {
        vec.push_back(std::make_pair<double, double>((7*i)%3, (3*i)%5));
    }
    std::sort(vec.begin(), vec.end(), [](std::pair<double, double> const & p1, std::pair<double, double> const & p2) {return (p1.first < p2.first) || ((p1.first==p2.first)&& (p1.second <= p2.second));}); 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

max*_*x66 14

尝试改变

(p1.second <= p2.second)
Run Code Online (Sandbox Code Playgroud)

(p1.second < p2.second)
Run Code Online (Sandbox Code Playgroud)

我的意思是...... std::sort()需要一个返回trueiff 的比较器(当且仅当)第一个参数(p1)严格低于第二个参数(p2).那就是:必须falsep1等于时返回p2.

如果您的考试是

   (p1.first < p2.first)
|| ((p1.first==p2.first)&& (p1.second <= p2.second))
Run Code Online (Sandbox Code Playgroud)

truep1等于时,你也得到了p2.

使用比较器,truep1等于时返回p2...如果我没有错,则行为未定义,因此"不稳定的行为"(以及分段错误)也是绝对可以理解的.


Hol*_*olt 11

这里的问题是你的lambda不符合标准要求Compare,这要求严格的弱排序:

  • 严格意味着!comp(x, x)必须对序列中的true每一个x都是如此,这与您的自定义比较器(lambda)的情况不同,因为comp(x, x) == true对于x您的情况中的每一个(x.first == x.first && x.second <= x.second).

您应该更改p1.second <= p2.secondp1.second < p2.second或使用标准比较运算符std::pair:

std::sort(vec.begin(), vec.end());
Run Code Online (Sandbox Code Playgroud)