如何优雅返回std::adjacent_find找到的第二个元素且无需处理未找到情况?
问题描述
想要返回std::adjacent_find找到的相邻元素对中的第二个元素迭代器,而非第一个,是否存在无需显式处理“未找到”特殊情况的优雅解决方案?希望实现与以下函数等效的功能,且无需自行重写std::adjacent_find的核心逻辑:
template<class Range, class Pred> auto adjacent_find_second(Range&& range, Pred pred) { auto it = std::ranges::adjacent_find(range, pred); if(it == range.end()) { return it; } else return ++it; }
已知std::adjacent_find的返回特性:它可返回范围内的任意迭代器(包括end()),但绝不会返回指向最后一个元素的迭代器(因为最后一个元素无法组成相邻对)。如果自行重写std::adjacent_find,可以直接返回配对中第二个元素的迭代器,无需额外检查,但希望能基于现有标准库实现该需求。
解决方案
可以利用std::ranges::next的重载特性,无需显式编写条件判断即可实现需求:
#include <ranges> #include <algorithm> template<class Range, class Pred> auto adjacent_find_second(Range&& range, Pred pred) { auto match_it = std::ranges::adjacent_find(range, pred); return std::ranges::next(match_it, 1, std::ranges::end(range)); }
原理说明
std::ranges::adjacent_find的返回特性保证:如果找到匹配的相邻对,返回的迭代器指向配对的第一个元素,且该迭代器绝不会是指向范围最后一个元素的迭代器(否则无法组成相邻对),因此对其执行一次递增操作是完全安全的。std::ranges::next(it, n, bound)的行为是:尝试将it递增n次,若在此过程中到达bound,则直接返回bound。当match_it是range.end()(未找到匹配)时,函数会直接返回range.end(),完全符合需求。
这个方案既避免了显式的条件判断,又复用了标准库的adjacent_find逻辑,同时保证了效率与安全性。
内容的提问来源于stack exchange,提问作者Henk
相关产品推荐
相关产品推荐

