std::可选::value_or() - 惰性参数评估

问题描述 投票:0回答:4

是否可以以惰性方式评估

std::optional::value_or(expr)
参数,因此仅在没有值的情况下才计算
expr

如果没有,什么是合适的替代品?

c++ stl c++17 stdoptional
4个回答
27
投票
#include <optional>

template <typename F>
struct Lazy
{
    F f;  

    operator decltype(f())() const
    {
        return f();
    }
};

template <typename F>
Lazy(F f) -> Lazy<F>;

int main()
{
    std::optional<int> o;

    int i = o.value_or(Lazy{[]{return 0;}});
}

演示


12
投票

您可以编写您的辅助函数:

template<typename T, typename F>
T lazy_value_or(const std::optional<T> &opt, F fn) {
    if(opt) return opt.value();
    return fn();
}

然后可以用作:

T t = lazy_value_or(opt, [] { return expensive_computation();});

如果这比明确地打字要少得多,那就由你来判断;不过,你可以用宏让它变得更短:

#define LAZY_VALUE_OR(opt, expr) \
    lazy_value_or((opt), [&] { return (expr);})

用作

T t = LAZY_VALUE_OR(opt, expensive_calculation());

这最接近我认为你想要的,但可能会让人皱眉,因为它隐藏了太多的东西。


0
投票

选择函数类型。

然后可以传入一个 lambda,在调用时将在请求的时刻计算出正确的值。

std::optional<std::function<int()>> opt;

int a = 42;
opt = [=] { return a; }

int b = 4;

int c = opt.value_or([=] { return b * 10 + 2;}) ();

0
投票

C++23 添加了一个密切相关的功能:https://en.cppreference.com/w/cpp/utility/optional/or_else

std::optional<int> f();
std::optional<int> g();

std::optional<int> y = f().or_else(g);

但请注意,

or_else()
参数本身返回
std::optional<T>
而不是
T

所以有 3 个选项,都比想象的要笨重一点:

  • 在 C++23 中,如果可用,请使用
    f().or_else(g).value()
    ,并且
    std::optional<T>
    参数的返回类型不会造成麻烦。
    使用像
  • or_else
  • 这样的辅助函数模板,牺牲一元方法链语法。
    写出
  • lazy_value_or(f(), g)
  • 
        
© www.soinside.com 2019 - 2024. All rights reserved.