different compare signature for std::upper_bound and std::lower_bound

空扰寡人 提交于 2019-12-04 06:29:06

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.

This generalizes from elem < value to comp(elem, value) and value < elem to comp(value, elem).

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<>{});

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.


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!