我正在尝试定义一个函数template<typename T> zero()
并将其专门用于各种情况。
zero<T>()
应该返回
static T::zero()
,如果存在。static_cast<T>(0)
。到目前为止很好,如下所述。
现在,我想以一种明智的方式将模板扩展到任何可以隐式转换为T
形式的std::function<Y(X...)>
,并应返回相应的归零函数[](X...){return zero<Y>();}
什么是最好的方法?
namespace hidden {
// tag dispatching
template<int r>
struct rank : rank<r - 1> {};
template<>
struct rank<0> {};
template<typename T>
auto zero(rank<2>) -> decltype(T::zero()) {
return T::zero();
}
template<typename T>
auto zero(rank<1>) -> decltype(static_cast<T>(0)) {
return static_cast<T>(0);
}
// This is where I need help
template<typename T>
auto zero(rank<0>) -> std::enable_if_t</* T is implicitly convertible to std::function<Y(X...)> */,T> {
using Y = // the type returned when an instance of T is invoked
return []() {
return zero<Y>();
};
}
}
template<typename T>
auto zero() { return hidden::zero<T>(rank<10>{}); }
我现在求助于每个预期签名的具体签名重复以下内容:
template<typename T>
auto zero(rank<0>)
-> std::enable_if_t<std::is_assignable<std::function<double(double)>, T>::value
, std::function<double(double)>> {
using Y = double;
return []() {
return zero<Y>();
};
}
但是我希望可以用模板魔术代替复制粘贴。
在c++17中有std::function
的推导指南: