![](/img/trans.png)
[英]If lambdas don't have a specified type, how does std::function accept a lambda?
[英]Does Comparison Function specified with lambda function in std::sort return bool type?
我正在阅读这段代码(来源):
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
int main() {
int number[] = {3, 5, 1, 6, 9};
auto print = [](int n) { cout << n << " "; };
sort(begin(number), end(number), [](int n1, int n2) { return n2 - n1; });
// result: 9 6 1 5 3
for_each(begin(number), end(number), print);
cout << endl;
sort(begin(number), end(number), [](int n1, int n2) { return n1 - n2; });
// result: 3 5 1 6 9
for_each(begin(number), end(number), print);
cout << endl;
return 0;
}
我对如何return n2 - n1;
vs return n1 - n2;
工作。
根据std::sort - cppreference.com ,它说comp是布尔类型function。 在 C++ 中,非零数始终具有真值(根据 Donegative numbers return false in C/C++? - 码客)。
所以上面例子中的number
里面有不同的项目总是会导致其中两个 lambda 函数返回true
。 也就是说,在这种情况下,那些 lambda 函数返回相同的结果。 但结果显示,一个是倒序的,一个是原序的。
我该如何解释这一点或我想念什么?
此处使用的比较函数无效。 如果 LHS 在预期的排序顺序中位于 RHS 之前,则传递给sort()
的 function 应该返回 true,否则返回 false(即它应该表现得像“小于”)。 这里的 lambda 表达式都没有这样的行为,因此使用这些函数中的任何一个调用sort()
都是未定义的行为。
在这两个调用中, sort()
最终反转了它给出的顺序。 这只是一个意外, sort()
碰巧在您的系统上实现的方式的意外随机副作用。 如果您尝试使用不同的编译器,您可能会得到不同的结果(例如崩溃)。
libstdc++ 中的std::sort
实现针对短序列进行了优化,在检查了source之后,我们知道对于短于 16 个元素的小序列,它将退回到插入排序。
在 c++ 中,非零数可以自动转换为布尔值true
,使用插入排序,如果你的序列没有相同的值,它会被反转(在插入排序循环中,所有值都会被移动到第一位,然后一旦循环完成,序列就会恢复)。
这不是确定性行为,因为 STL 实现可能彼此不同,并且 _S_threshold 数字未向最终用户透露。
将数组扩大到超过 16 个元素,我们得到完全不同的结果:
程序因缓冲区溢出而崩溃! 所以现在我们证明使用这种类型的 lambda [](int n1, int n2) { return n2 - n1; }
是错误的。 [](int n1, int n2) { return n2 - n1; }
,正确的方式应该是sort(begin(number), end(number), [](int n1, int n2) { return n2 > n1; });
#include <iostream>
#include <functional>
#include <algorithm>
using namespace std;
int main() {
int number[] = {3, 5, 1, 6, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
auto print = [](int n) { cout << n << " "; };
sort(begin(number), end(number), [](int n1, int n2) { return n2 - n1; });
for_each(begin(number), end(number), print);
cout << endl;
sort(begin(number), end(number), [](int n1, int n2) { return n1 - n2; });
for_each(begin(number), end(number), print);
cout << endl;
return 0;
}
n2 - n1
在作为结果为负数的情况下转换为bool
时将产生true
。 所以n1
结果小于n2
。 这就是为什么在这种 Boolean 上下文中使用int
是一种不好的做法。
是的,如文档中所述:
...比较 function object 如果第一个参数小于第二个参数,则返回 true
但是这里比较的实现会导致失败。 试试这个,自己看看:
int x = 5, y = 555;
bool b = x - y;
std::cout << b << std::endl; // Prints 1, means true
提供的比较 function 必须遵循operator<
的逻辑。 所以,当你的 lambda 有n1 = 5, n2 = 1;
n2 - n1
的结果是-4
在 Boolean 上下文中使用时( bool
是无符号的)被转换为1
。
结果你有5 < 1
is true 。
虽然在您的 output 中 1 放在 5 之后,但这种错误比较会导致整体结果不理想。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.