web-dev-qa-db-ja.com

std :: optional :: value_or()-怠惰な引数の評価

std::optional::value_or(expr)引数を怠惰な方法で評価することは可能ですか?したがって、exprは、値がない場合にのみ計算されましたか?

そうでない場合、適切な代替品は何でしょうか?

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

[〜#〜]デモ[〜#〜]

23
Piotr Skotnicki

ヘルパー関数を書くことができます:

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

これは私があなたが望むと思うものに最も近いですが、それは少し多くのものを隠しているので眉をひそめるかもしれません。

9
Matteo Italia

関数型のオプションを作成します。

次に、ラムダを渡すことができます。ラムダが呼び出されると、要求された瞬間に正しい値が計算されます。

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