在介绍视图(view)前,先简单介绍一下许多基于范围的算法的一个额外功能——投影(projection)。
与std
命名空间中相对应的算法不同,一些std::ranges
算法支持一种额外的功能:投影。
假定我们想要对一个Box
序列排序,并且想按照它们的高度而不是体积进行排序。在C++17中通过如下语句完成:
std::sort(begin(boxes), end(boxes),
[](const Box& one, const Box& other) {
return one.getHeight() < other.getHeight();
}
);
而在C++20中,可以用下面的语句:
std::ranges::sort(boxes, std::less<>{},
[](const Box& box) {
return box.getHeight();
}
);
在把元素传递给比较函数之前,先将其传递给投影函数进行。
在本实例中,在将Box
传递给泛型std::less<>{}
函子之前,投影函数会将所有的Box
转换为对应的高度值。
换言之,std::less<>{}
函子总是会接收两个double
类型的值,它并不知道我们实际上是在对Box
进行排序,而不是对double
类型的值进行排序。
可选的投影参数甚至可以是指向(无参数)成员函数的指针,或者是指向(公共)成员变量的指针。这种纯粹优雅的方式最好用一个示例来演示:
std::ranges::sort(boxes, std::less<>{}, &Box::getHeight);
// 或者:
std::ranges::sort(boxes, std::less<>{}, &Box::m_height); //此处m_height应该是public的
当调用每个对象的成员函数,或者从每个对象读取给定成员变量的值时,就会用到投影功能。