【发布时间】:2021-03-30 17:10:00
【问题描述】:
在 Java 中,Stream.findFirst() returns 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;
}
【问题讨论】:
-
您始终可以编写一个包装函数来封装
.end()的检查。无需到处复制代码。 -
考虑一下,我实际上想要一个包装器,1) 从
borrowed_iterator<T>转换为std::optional<T>,以及 2) 允许投影从T中提取成员。您能否在回答中提供此类包装器的模板示例? -
Anyway,
op*andop->simply assume they are used correctly on pain of UB. 是的,!result比result == std::end(container)更方便一点,但这与直接使用迭代器相平衡。此外,可选的迭代器通常比简单的迭代器大...
标签: c++ c++20 stdoptional