问题描述
我正在尝试在std::optional
上以monad风格编写语法糖.请考虑:
I'm trying to write syntactic sugar, in a monad-style, over std::optional
. Please consider:
template<class T>
void f(std::optional<T>)
{}
就这样,即使存在从T
到std::optional<T>
T (例如int
)调用此函数. sup> 2 .
As is, this function cannot be called with a non-optional T
(e.g. an int
), even though there exists a conversion from T
to std::optional<T>
.
是否有一种方法可以使f
接受std::optional<T>
或T
(在调用者站点上转换为可选),而无需定义重载 ?
Is there a way to make f
accept an std::optional<T>
or a T
(converted to an optional at the caller site), without defining an overload?
f(0)
:error: no matching function for call to 'f(int)'
和note: template argument deduction/substitution failed
,(演示).
因为模板参数推导不考虑转换.
对于一元函数,重载是可以接受的解决方案,但是当您拥有像operator+(optional, optional)
这样的二进制函数时,重载就变得很烦人,而对于三元,4元,等而言,这是一个痛苦. 函数.
f(0)
: error: no matching function for call to 'f(int)'
and note: template argument deduction/substitution failed
, (demo).
Because template argument deduction doesn't consider conversions.
Overloading is an acceptable solution for a unary function, but starts to be an annoyance when you have binary functions like operator+(optional, optional)
, and is a pain for ternary, 4-ary, etc. functions.
推荐答案
另一个版本.这不涉及任何内容:
Another version. This one doesn't involve anything:
template <typename T>
void f(T&& t) {
std::optional opt = std::forward<T>(t);
}
类模板参数推论已经在这里做对了.如果t
是optional
,将首选复制扣除对象,并且我们会得到相同的类型.否则,我们将其包装.
Class template argument deduction already does the right thing here. If t
is an optional
, the copy deduction candidate will be preferred and we get the same type back. Otherwise, we wrap it.
这篇关于使函数接受可选选项以接受非可选选项吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!