是否有一种紧凑的方法可以使 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->b, maybe_s->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中初始化数组的功能方法?
是否有一种解决方法可以使名称以数字开头的 CSS 类有效? [复制]