std :: upper_bound和std :: lower_bound的不同比较签名 [英] different compare signature for std::upper_bound and std::lower_bound

查看:104
本文介绍了std :: upper_bound和std :: lower_bound的不同比较签名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是 std :: lower_bound & std :: upper_bound ,请注意将比较lambda的签名传递给他们-

Here is a sample example for both std::lower_bound & std::upper_bound, notice the signature of Compare lambda being passed to them -

const auto lower_x = std::lower_bound(
          points.begin(), points.end(), rec.min_corner.x,

          [](const RankedPoint &rp, const double x) { return rp.point.x < x; });

const auto upper_x = std::upper_bound(
          points.begin(), points.end(), rec.max_corner.x,

          [](const double x, const RankedPoint &rp) { return x < rp.point.x; });

将签名保持完全相反的背后可能是什么原因?我没有意识到这一点,当我使用 auto 而不是带有错误签名的确定类型时,gcc对其进行了编译(clang没有)。花了我10分钟的挫败感。

What is the possible reasoning behind keeping the signature exact opposite of each other? I wasn't aware of this and gcc compiled (clang didn't) it when I used auto instead of definite types with wrong signatures. Costed me 10 minutes of frustration.

推荐答案

自定义比较器版本的 lower_bound upper_bound 是仅使用< 的概括。 lower_bound 产生的第一个元素不少于 value ,因此要进行的检查是元素<值(或!(元素<值)确实)。 upper_bound 产生比 value 大的第一个元素更大,但是我们不是写 elem>值(这需要 operator> ),我们只需将顺序翻转为 value<元素。这保持了 operator< 的唯一要求,但结果是参数的顺序颠倒了。

The custom comparator versions of lower_bound and upper_bound are generalizations of simply using <. lower_bound yields the first element that is not less than value, so the check that happens is elem < value (or !(elem < value) really). upper_bound yields the first element greater than value, but we instead of writing elem > value (which would require operator>), we just flip the ordering to value < elem. This maintains the sole requirement of operator<, but as a result, the order of arguments is reversed.

此从 elem<中概括。 value comp(elem,value) value< elem comp(value,elem)

最终,在设计时可以做出两种选择:我们可以在各处使用 same 比较器,但是对于某些算法,顺序的参数是相反的。或者,对于每种算法,我们可以使用不同比较器,具体取决于哪种算法有意义。在各处使用相同的比较器有很多优点-您只需使用相同的比较器即可:

Ultimately, there are two choices that we could make when designing this: we could use the same comparator everywhere, but for some algorithms the order of arguments is reversed. Or, we could use different comparators for every algorithm, depending on what makes sense for that particular algorithm. Using the same comparator everywhere has a lot of advantages - you just use the same comparator:

std::vector<int> vs = ...;
std::sort(vs.begin(), vs.end(), std::greater<>{});
auto lo = std::lower_bound(vs.begin(), vs.end(), 5, std::greater<>{});
auto hi = std::upper_bound(vs.begin(), vs.end(), 5, std::greater<>{});

到处都是相同的比较器,代码看起来正确,并且做对了。如果我们反转 upper_bound()传递给其比较器的参数顺序,则必须传递 std :: less<> { } 。那只是...看起来错了。

Same comparator everywhere, code looks correct, and does the right thing. If we flipped the order of arguments that upper_bound() passes to its comparator, we'd have to pass in std::less<>{}. Which would just... look wrong.

您可能会对范围TS ,它可以解决可调用投影的问题。

You'll probably be interested in the Ranges TS, which solves this problem with invokable projections.

这篇关于std :: upper_bound和std :: lower_bound的不同比较签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆