c++ - C++ 范围像 Java 流一样查找并返回 std::optional
问题描述
在 Java 中,Stream.findFirst()
返回Optional<T>
. 我想对std::ranges::find()
. 如果未找到该值,则返回last
迭代器。如果T
是一个结构,这很不方便,我试图从中取出一个成员。这是一个演示代码:
struct Person {
int age;
int height;
};
std::vector<Person> people;
people.emplace_back(20, 100);
people.emplace_back(23, 170);
// find the height of a 23yo person
std::optional<int> height1 = std::ranges::find(people, 23, &Person::age)->height;
// find the height of a 26yo person
std::optional<int> height2 = std::ranges::find(people, 26, &Person::age)->height; // error
当然,我可以在每个周围放置一些包装器代码find
来转换迭代器,但这会使代码变得如此冗长和样板式。我想知道 C++20 中是否有一些更惯用的方式来做到这一点?
std::optional<int> height2;
auto iter = std::ranges::find(people, 26, &Person::age);
if (iter == people.end()) {
height2 = std::nullopt;
} else {
height2 = iter->height;
}
解决方案
template <class ...ArgsT>
auto OpRangesFind(auto &&Range, ArgsT &&...Args)
{
auto Iter = std::ranges::find(Range, std::forward<ArgsT>(Args)...);
return Iter != Range.end() ? Iter : std::optional<decltype(Iter)>{std::nullopt};
}
int main()
{
/* ... */
auto OpIter = OpRangesFind(people, 26, &Person::age);
if (!OpIter.has_value()) {
std::cout << "not found\n";
} else {
std::cout << "found\n";
std::cout << "height: " << OpIter.value()->height << "\n";
// ^^^^^^^^
}
}
推荐阅读
- java - Spring Webflux:如何比较两个 Mono 流的结果并基于过滤器保存
- javascript - Vuejs SearchBar ||使用过滤方法不起作用
- mysql - 如果另一列是 3,则返回列,否则返回 0
- linux - 如何从源代码安装 ubuntu-desktop?
- git - 使子模块中的 git commit 可用于其他本地存储库
- python - PySimpleGUI - 我无法在浏览器上获得任何输出
- c++ - CRTP 和向下转换
- reactjs - 将前端部署到 GitHub 页面,将后端部署到 Heroku
- typescript - 如何将 dd.MM.yyyy 字符串转换为 Date 对象
- c# - 从 Azure 函数对 FTP 服务器(活动模式)运行 C# FTP 客户端 - “500 语法错误,命令无法识别”