std :: optional :: value_or() - оценка ленивого аргумента Можно ли оценивать аргумент std::optional::value_or(expr) ленивым способом, поэтому expr было рассчитано только в случае отсутствия значения? Если нет, то что будет подходящей заменой? Ответ 1 #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 Ответ 2 Вы можете написать свою вспомогательную функцию: 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()); Это ближе всего к тому, что я думаю, что вы хотите, но его можно смутить, поскольку он скрывает слишком много вещей. Ответ 3 Сделайте необязательным тип функции. Затем может быть передан лямбда, который при вызове будет вычислять правильное значение в заданный момент. std::optional<std::function<int()>> opt; int a = 42; opt = [=] { return a; } int b = 4; int c = opt.value_or([=] { return b * 10 + 2;}) ();
Ответ 1 #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
Ответ 2 Вы можете написать свою вспомогательную функцию: 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()); Это ближе всего к тому, что я думаю, что вы хотите, но его можно смутить, поскольку он скрывает слишком много вещей.
Ответ 3 Сделайте необязательным тип функции. Затем может быть передан лямбда, который при вызове будет вычислять правильное значение в заданный момент. std::optional<std::function<int()>> opt; int a = 42; opt = [=] { return a; } int b = 4; int c = opt.value_or([=] { return b * 10 + 2;}) ();