ranges::max
时间: 2025-03-15 07:06:19 浏览: 50
### 关于 `ranges::max` 的用法与实现
在 C++20 中引入的 Ranges 库极大地增强了标准库的功能,使得处理范围操作更加简洁和高效。`std::ranges::max` 是该库的一部分,用于返回指定范围内最大的元素。
#### 函数签名
以下是 `std::ranges::max` 的函数签名:
```cpp
template< std::input_iterator I, std::sentinel_for<I> S,
class Proj = std::identity,
std::indirect_strict_weak_order<std::projected<I,Proj>> Comp = std::less<> >
constexpr auto max(I first, S last, Comp comp = {}, Proj proj = {}) -> decltype(auto);
template< std::ranges::input_range R,
class Proj = std::identity,
std::indirect_strict_weak_order<
std::projected<std::ranges::iterator_t<R>, Proj>> Comp = std::less<>>
constexpr auto max(R&& r, Comp comp = {}, Proj proj = {}) -> decltype(auto);
```
上述定义表明 `std::ranges::max` 支持两种调用方式:基于迭代器对 `[first, last)` 范围的操作以及基于范围对象的方式[^2]。
#### 参数说明
- **输入范围** (`I`, `S`) 或者范围对象 (`R`):表示要比较的最大值所在的集合。
- **自定义投影函数** (`Proj`):允许通过特定逻辑映射原始数据后再进行比较。
- **自定义比较器** (`Comp`):可以提供一个二元谓词来替代默认的小于运算符 `<` 进行最大值判断。
#### 实现细节
下面是一个简单的实现示例,展示了如何利用模板参数推导机制完成这一功能:
```cpp
#include <concepts>
#include <functional>
#include <iterator>
namespace my_ranges {
template<typename T, typename Proj = std::identity, typename Comp = std::less<>>
constexpr const T& max(const T& a, const T& b, Comp cmp = {}, Proj proj = {}) {
return !cmp(proj(b), proj(a)) ? a : b;
}
template<std::input_iterator Iter, std::sentinel_for<Iter> Sent,
typename Proj = std::identity,
typename Comp = std::less<decltype(std::declval<Proj>()(*std::declval<Iter>()))>>
constexpr auto max(Iter begin, Sent end, Comp cmp = {}, Proj proj = {})
->decltype(*begin) {
if (begin == end) throw std::invalid_argument("Empty range");
auto largest = begin;
for (auto it = std::next(begin); it != end; ++it) {
if (!cmp(proj(*largest), proj(*it))) {
largest = it;
}
}
return *largest;
}
}
```
此代码片段实现了两个版本的 `my_ranges::max` 方法,分别针对单个元素对比及整个序列扫描的情况进行了覆盖[^3]。
#### 使用案例
这里给出几个实际应用的例子帮助理解其灵活性:
```cpp
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main() {
vector<int> v{1, 7, 3};
cout << "Max value: " << ranges::max(v.begin(), v.end()) << endl; // 默认行为
string s{"hello"};
char c_max = ranges::max(s.begin(), s.end());
cout << "Max character in 'hello': " << c_max << endl;
struct Person { int age; };
vector<Person> people{{28}, {45}, {19}};
auto oldest_person = ranges::max_element(
people.begin(),
people.end(),
{},
[](const Person &p){return p.age;}
);
cout << "Oldest person's age: " << (*oldest_person).age << endl;
}
```
以上程序演示了不同类型的数据结构上寻找最大值的过程,并且最后还加入了带有投影变换的情形[^4]。
---
阅读全文
相关推荐



















