[英]Iterating over std::optional
I tried to iterate over an std::optional
:我试图迭代一个std::optional
:
for (auto x : optionalValue)
{
...
}
With the expectation of it doing nothing if optionalValue
is empty but doing one iteration if there is a value within, like it would work in Haskell (which arguably made std::optional
trendy):如果optionalValue
为空,则期望它什么也不做,但如果其中有一个值,则执行一次迭代,就像它在 Haskell 中工作一样(可以说这使std::optional
成为时尚):
forM optionalValue
( \x ->
...
)
Why can't I iterate an optional?为什么我不能迭代一个可选项? Is there another more standard C++ method to do this?是否有另一种更标准的 C++ 方法来执行此操作?
std::optional
does not have a begin()
and end()
pair. std::optional
没有begin()
和end()
对。 So you cannot range-based-for over it.因此,您不能对其进行基于范围的处理。 Instead just use an if
conditional.相反,只需使用if
条件。
See Alternative 2 for the closest thing to what you want to do.请参阅备选方案 2,了解与您想要做的最接近的事情。
Edit: If you have a temporary from a call result you don't have to check it explicitly:编辑:如果你有一个临时的呼叫结果,你不必明确地检查它:
if (auto const opt = function_call()) {
do_smth(*opt);
}
The check for static_cast<bool>(opt)
is done implicitly by if
. static_cast<bool>(opt)
的检查由if
隐式完成。
Alternative 1备选方案 1
Another alternative is to not use an std::optional<T>
but std::variant<std::monostate, T>
.另一种选择是不使用std::optional<T>
而是使用std::variant<std::monostate, T>
。 You can then either use the overloaded
idiom or create a custom type to handle the monostate:然后,您可以使用overloaded
的习惯用法或创建自定义类型来处理单态:
template <typename F>
struct MaybeDo {
F f;
void operator()(std::monostate) const {}
template <typename T>
void operator()(T const& t) const { f(t); }
};
which will allow you to visit the value with some function:这将允许您使用某些功能访问该值:
std::variant<std::monostate, int> const opt = 7;
std::visit(MaybeDo{[](int i) { std::cout << i << "\n"; }}, opt);
Alternative 2备选方案 2
You can also wrap optional in a thing that allows you to iterate over it.您还可以将 optional 包装在允许您对其进行迭代的事物中。 Idea:主意:
template <typename T>
struct IterateOpt {
std::optional<T> const& opt;
struct It {
std::optional<T> const* p;
It& operator++() {
p = nullptr;
return *this;
}
It operator++(int) {
return It{nullptr};
}
auto const& operator*() const { **p; }
};
auto begin() const {
if (opt) return It{&opt};
else end();
}
auto end() const {
return It{nullptr};
}
};
This is a crude sketch of how to do this and probably requires some love to work on different situations (like a non-const optional).这是如何做到这一点的粗略草图,可能需要一些爱来处理不同的情况(比如非常量可选)。
You can use this to "iterate" over the optional:您可以使用它来“迭代”可选:
for (auto const& v: IterateOpt{function_call()}) {
do_smth(v);
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.