【问题标题】:Extending/specializing `template<typename T>zero()` to invocable `T`将 `template<typename T>zero()` 扩展/特化为可调用的 `T`
【发布时间】:2020-06-08 05:39:18
【问题描述】:

我正在尝试定义一个函数 template&lt;typename T&gt; zero() 并将其专门用于各种情况。

zero&lt;T&gt;() 应该返回

  • static T::zero() 如果存在。
  • 否则static_cast&lt;T&gt;(0) 如果已定义。

到目前为止一切顺利,如下所示。

现在我想以一种合理的方式将模板扩展到任何T,它可以隐式转换为std::function&lt;Y(X...)&gt; 形式的类型,并且应该返回相应的归零函数[](X...){return zero&lt;Y&gt;();}

最好的方法是什么?

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++ templates c++14 template-meta-programming sfinae


    【解决方案1】:

    中带有std::function 的推演指南:

    template <typename T,
              typename F = decltype(std::function{std::declval<T>()}),
              typename Y = typename F::result_type>
    F zero(rank<0>) {
        return [](auto&&...) {
            return zero<Y>(rank<10>{});
        };
    }
    

    DEMO

    你需要自己写this trait


    但是请注意,如果 T::operator() 被重载或表示函数模板(包括通用 lambda 表达式),这将不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多