是否有一种紧凑的方法可以使 std::optional<T>::value_or 对 T 的成员变量起作用

Posted

技术标签:

【中文标题】是否有一种紧凑的方法可以使 std::optional<T>::value_or 对 T 的成员变量起作用【英文标题】:Is there a compact way to make std::optional<T>::value_or work on member variables of 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_optS11, 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;
    

【问题讨论】:

虽然(还没有)在标准中,但P0798R6(std::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(S0, 100); ? @dfrib 这是一个 愤怒的提案不在 C++ 中,特别是因为这部分:我找不到任何其他人 Afaict it was recently approved for C++23. @dfrib 好消息! 【参考方案1】:

虽然还没有在标准中,P0798R6(std::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

【讨论】:

以上是关于是否有一种紧凑的方法可以使 std::optional<T>::value_or 对 T 的成员变量起作用的主要内容,如果未能解决你的问题,请参考以下文章

是否有一种在JavaScript ES6中初始化数组的功能方法?

是否可以以紧凑的方式使用 Mockito 验证任意交互?

我有37个变量;是否有一种整洁的方法可以返回最大值?

是否有一种解决方法可以使名称以数字开头的 CSS 类有效? [复制]

是否有一种 FastAPI 方法可以在全球范围内访问当前的请求数据?

是否有一种标准化的方法可以在 Python 中交换两个变量?