Enr*_*lis 4 c++ performance c++20 std-ranges c++23
std::begin.begin如果参数有成员函数,则可以调用该成员函数。似乎也std::ranges::begin做同样的事情。
但是,在 的 页面上,std::ranges::contains我没有看到提及member一词,也没有看到.contains. 这是为什么?
我的意思是,如果我要写,std::ranges::contains(someRange, someVal)我真的希望它会导致对 member 的调用contains,如果someRange碰巧是 astd::map和someVala key 。
我还查看了ranges::containsRange-v3,在我看来,它也只是在范围内进行线性搜索,对支持 member 的参数没有特殊处理contains。
我的意思是,如果我要写,
std::ranges::contains(someRange, someVal)我真的希望它会导致对 member 的调用contains,如果someRange碰巧是 astd::map和someVala key 。
问题是这些含义非常不同。给定 a std::map<int, string> m,m.contains(42)检查键 42是否存在于映射中,但ranges::contains(m, 42)会检查是否作为范围内的值42存在- 但值类型是,它与 不可比较,因此这甚至无法编译。pair<int const, string>int
这两种算法只是做不同的事情,所以你不能尝试ranges::contains(m, v)调用m.contains(v). string这对于和来说是正确的(尽管不必要)string_view。它可能是正确的并且是对 的改进,set但也可能是错误的(见下文),但对于 则可能是错误的map。
对于其他算法也是如此,其中通用算法基于整个值类型,但某些特定容器仅将算法应用于键(例如find、count等)。
尝试检查是否m.contains(v)成为一个问题,因为这些东西通常在存在松散约束的情况下往往非常脆弱(也许表达式是有效的,因为它没有约束,但应该有)或更灵活的类型(也许是某种类型只是比较等于所有内容,因此约束具有误导性 - 这里的规范示例是std::any在考虑可构造性规则时使用的)。
即使所有约束都是合法的并且以合理的方式传递,但这仍然并不意味着使用成员算法是正确的。例如:
struct Point {
int x, y;
friend auto operator==(Point, Point) -> bool = default;
};
struct JustXs {
auto operator()(Point a, Point b) const -> bool {
return a.x < b.x;
}
};
int main() {
std::set<Point, JustXs> points = {Point{1, 2}};
bool a = points.contains(Point{1, 3}); // true
bool b = std::ranges::contains(points, Point{1, 3}); // false
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
634 次 |
| 最近记录: |