GCC的std :: sort与lambdas的不稳定行为
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GCC的std :: sort与lambdas的不稳定行为相关的知识,希望对你有一定的参考价值。
使用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;
}
答案
尝试改变
(p1.second <= p2.second)
同
(p1.second < p2.second)
我的意思是...... std::sort()
需要一个比较器返回true
iff(当且仅当)第一个参数(p1
)严格低于第二个参数(p2
)。那就是:当false
等于p1
时,必须返回p2
。
如果您的考试是
(p1.first < p2.first)
|| ((p1.first==p2.first)&& (p1.second <= p2.second))
当true
等于p1
时,你也获得p2
。
当true
等于p1
时,使用比较器返回p2
...如果我没有错,则行为未定义,因此“不稳定行为”(以及分段错误)也是绝对可以理解的。
另一答案
这里的问题是你的lambda不符合Compare
的标准要求,这要求严格的弱排序:
- 严格意味着
!comp(x, x)
必须是序列中每个true
的x
,这不是你的自定义比较器(lambda)的情况,因为comp(x, x) == true
为你的情况下每个x
(x.first == x.first && x.second <= x.second
)。
你应该将p1.second <= p2.second
更改为p1.second < p2.second
,或者使用std::pair
的标准比较运算符:
std::sort(vec.begin(), vec.end());
另一答案
Libstdc ++有一个debug mode,可以通过定义宏_GLIBCXX_DEBUG
来启用。
$ g++-6 b.cc -D_GLIBCXX_DEBUG && ./a.out
/usr/include/c++/6/bits/stl_algo.h:4737:
Error: comparison doesn't meet irreflexive requirements, assert(!(a < a)).
Objects involved in the operation:
instance "functor" @ 0x0x7ffe48ba5a20 {
type = main::{lambda(std::pair<double, double> const&, std::pair<double, double> const&)#1};
}
iterator::value_type "ordered type" {
type = std::pair<double, double>;
}
以上是关于GCC的std :: sort与lambdas的不稳定行为的主要内容,如果未能解决你的问题,请参考以下文章
错误“lambda不是从'std :: function'派生的
错误“lambda 不是从 'std::function' 派生的