我试着在std::optional上写:
std::optional
for (auto x : optionalValue){ ...}
for (auto x : optionalValue)
{
...
}
字符串如果optionalValue是空的,它什么也不做,但是如果里面有一个值,它会做一次迭代,就像它在Haskell中一样(这可以说使std::optional流行起来):
optionalValue
forM optionalValue( \x -> ...)
forM optionalValue
( \x ->
)
型为什么我不能选择可选的?有没有其他更标准的C++方法可以做到这一点?
vx6bjr1n1#
std::optional没有begin()和end()对。所以你不能在上面使用基于范围的-for。而只需要使用if条件。
begin()
end()
if
编辑:如果你有一个临时的调用结果,你不必显式地检查它:
if (auto const opt = function_call()) { do_smth(*opt);}
if (auto const opt = function_call()) {
do_smth(*opt);
字符串static_cast<bool>(opt)的检查由if隐式完成。
static_cast<bool>(opt)
备选案文1
另一种选择是不使用std::optional<T>,而是使用std::variant<std::monostate, T>。然后您可以使用overloaded习惯用法或创建自定义类型来处理单态:
std::optional<T>
std::variant<std::monostate, T>
overloaded
template <typename F>struct MaybeDo { F f; void operator()(std::monostate) const {} template <typename T> void operator()(T const& t) const { f(t); }};
template <typename F>
struct MaybeDo {
F f;
void operator()(std::monostate) const {}
template <typename T>
void operator()(T const& t) const { f(t); }
};
型这将允许您使用某些函数访问该值:
std::variant<std::monostate, int> const opt = 7;std::visit(MaybeDo{[](int i) { std::cout << i << "\n"; }}, opt);
std::variant<std::monostate, int> const opt = 7;
std::visit(MaybeDo{[](int i) { std::cout << i << "\n"; }}, opt);
型
你也可以把optional Package 在一个东西里,这样你就可以把optional覆盖在上面。
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}; }};
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 {
型这是如何做到这一点的粗略草图,可能需要一些爱来处理不同的情况(如非常数可选)。您可以使用此命令“删除”可选的:
for (auto const& v: IterateOpt{function_call()}) { do_smth(v);)
for (auto const& v: IterateOpt{function_call()}) {
do_smth(v);
dly7yett2#
你可以使用类似于
for (const auto& x : optionalValue.value()){ //code}
for (const auto& x : optionalValue.value()){
//code
字符串这可以抛出std::bad_optional_accesshttps://en.cppreference.com/w/cpp/utility/optional/valuehttps://devblogs.microsoft.com/oldnewthing/20211004-00/?p=105754
std::bad_optional_access
2条答案
按热度按时间vx6bjr1n1#
std::optional
没有begin()
和end()
对。所以你不能在上面使用基于范围的-for。而只需要使用if
条件。编辑:如果你有一个临时的调用结果,你不必显式地检查它:
字符串
static_cast<bool>(opt)
的检查由if
隐式完成。备选案文1
另一种选择是不使用
std::optional<T>
,而是使用std::variant<std::monostate, T>
。然后您可以使用overloaded
习惯用法或创建自定义类型来处理单态:型
这将允许您使用某些函数访问该值:
型
你也可以把optional Package 在一个东西里,这样你就可以把optional覆盖在上面。
型
这是如何做到这一点的粗略草图,可能需要一些爱来处理不同的情况(如非常数可选)。
您可以使用此命令“删除”可选的:
型
dly7yett2#
你可以使用类似于
字符串
这可以抛出
std::bad_optional_access
https://en.cppreference.com/w/cpp/utility/optional/valuehttps://devblogs.microsoft.com/oldnewthing/20211004-00/?p=105754