range-v3的meta :: defer的实现如何工作?

时间:2018-12-23 15:37:23

标签: c++ template-meta-programming deferred-execution range-v3

这是meta::defer的实现:

template <template <typename...> class C, typename... Ts>
struct defer : detail::defer_<C, Ts...> {};

detail::defer_

template <template <typename...> class C, typename... Ts>
using defer_ = decltype(detail::try_defer_<C, Ts...>(0));

detail::try_defer

    template <template <typename...> class C, typename... Ts,
              template <typename...> class D = C>
    id<D<Ts...>> try_defer_(int);
    template <template <typename...> class C, typename... Ts> nil_ try_defer_(long);

struct id

    template <typename T> struct id {
    #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 5 &&                \
        !defined(META_DOXYGEN_INVOKED)
      // Redirect through decltype for compilers that have not
      // yet implemented CWG 1558:
      // <http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1558>
      static id impl(void *);

      template <typename... Ts>
      using invoke = _t<decltype(id::impl(static_cast<list<Ts...> *>(nullptr)))>;
    #else
      template <typename...> using invoke = T;
    #endif

      using type = T;
    };

struct nil_ {};

official doc(example use case)

  

一个包装器,用于在lambda或let表达式中延迟类型参数Ts的模板C的实例化。

     

在下面的代码中,理想情况下,lambda将被编写为lambda <_a,_b,push_back <_a,_b >>,但是由于push_back期望其第一个参数为列表而不是占位符,所以此操作失败。相反,我们使用defer表示它,如下所示:

template<typename List>
using reverse = reverse_fold<List, list<>, lambda<_a, _b, defer<push_back, _a, _b>>>;

根据用例,meta::defer似乎将表达式推迟到SFINAE起作用为止。但是我无法弄清楚实现是如何工作的。

问题

1。 meta::defer如何工作?

2。 libcxx也有一个struct __dependent_type,其定义是:

template <class _Tp, bool>
struct _LIBCPP_TEMPLATE_VIS __dependent_type : public _Tp {};

I also ask a question about __dependent_type(为避免重复,我不在此放置__dependent_type的详细信息)

如果meta::defer仅是为了延迟SFINAE的表达式,是否可以将其替换为上面的__dependent_type,为什么?

0 个答案:

没有答案