【问题标题】:Is there a compact way to make std::optional<T>::value_or work on member variables of T是否有一种紧凑的方法可以使 std::optional<T>::value_or 对 T 的成员变量起作用
【发布时间】:2021-11-21 07:39:10
【问题描述】:

考虑以下代码:

#include <iostream>
#include <optional>
struct S{
    int b;
    int e;
};

void fn(const std::optional<S>& maybe_s){
    int begin = maybe_s? maybe_s-> b: 0;
    int end = maybe_s? maybe_s->e : 100;
    std::cout << begin << "    " << end << std::endl;
}

int main() {
    std::optional<S> empty_opt;
    fn(empty_opt);
    std::optional<S> active_opt{S{11, 47}};
    fn(active_opt);
}

在这里,我想要value_or 之类的东西,但不是针对S,而是针对它的成员。 有没有办法在 C++ 中很好地做到这一点?

请注意,我希望它在类初始化器列表中工作,所以我不能使用结构化绑定。

我有这个解决方案,但如果可能的话,我更喜欢使用std:: 中的东西(便于新开发人员阅读,而且我的解决方案可能存在性能问题+没有适当的限制,例如 V 必须可转换为调用的结果...)。

template<typename T, typename M, typename V>
decltype(auto) memb_or(const std::optional<T>& opt, M m, const V& default_val){
    if (opt){
        return std::invoke(m, *opt);
    } else {
        return default_val;
    }
}

【问题讨论】:

  • 虽然(还没有)在标准中,但P0798R6std::optional 的单子操作)可能会为您正在寻找的东西提供一些糖,即在Sy Brand's std::optional implementation中实现。
  • auto [begin, end] = maybe_s ? std::pair(maybe_s-&gt;b, maybe_s-&gt;e) : std::pair(0, 100);auto [begin, end] = maybe_s.value_or(S{0, 100}); ?
  • @dfrib 这是一个 愤怒的提案不在 C++ 中,特别是因为这部分:我找不到任何其他人
  • @dfrib 好消息!

标签: c++ c++20 stdoptional


【解决方案1】:

虽然还没有在标准中,P0798R6std::optional)可能会为您正在寻找的东西提供一些糖,这在 Sy Brand's std::optional implementation 中实现。

看起来提案只是recently approved for C++23

JeffGarland 于 7 月 10 日发表评论

LWG 于 2021-07-09 完成审查

投票:对 C++23 的 std::optional 采用 D0798R8 Monadic 操作?

F  A  N
7  0  0

【讨论】:

    猜你喜欢
    • 2017-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 2023-02-16
    • 2010-12-01
    • 1970-01-01
    相关资源
    最近更新 更多