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

时间:2018-08-05 15:12:17

标签: c++ stl c++17 stdoptional

是否可以以惰性方式计算std::optional::value_or(expr)参数,所以expr仅在没有值的情况下计算?

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

3 个答案:

答案 0 :(得分:22)

#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;}});
}

DEMO

答案 1 :(得分:9)

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

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());

这与我想您想要的最接近,但是可能因为它隐藏了太多东西而被皱了皱眉。

答案 2 :(得分:0)

使函数类型为可选。

然后可以传入一个lambda,在调用该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;}) ();