1

Here is the implementation of 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)

A wrapper that defers the instantiation of a template C with type parameters Ts in a lambda or let expression.

In the code below, the lambda would ideally be written as lambda<_a,_b,push_back<_a,_b>>, however this fails since push_back expects its first argument to be a list, not a placeholder. Instead, we express it using defer as follows:

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

According to the use case, meta::defer seems to defer the expression until SFINAE work. But I cannot figure out how does the implementation work.

Question

1. How does meta::defer work?

2. libcxx also has a struct __dependent_type, whose definition is:

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

and I also ask a question about __dependent_type(to avoid repetitions, I don't put details of __dependent_type here)

If meta::defer is just to defer the expression for SFINAE, is it possible to replace it with __dependent_type above, and why?

Chen Li
  • 4,824
  • 3
  • 28
  • 55
  • "Here is the implementation of meta::defer" - Are you sure? Following your "official doc" link, and corresponding "meta.hpp", I see `defer` inherits from `detail::defer_>`. And other differences. – max66 Dec 23 '18 at 16:05
  • @max66 I guess in doc, `list` is just for more readable. In source code, the details are as I list. You can see this commit, whichis found from git blame: https://github.com/ericniebler/range-v3/commit/304b5664dcb2044b9ab7a7df9862a0314480e614#diff-305c0246765a6a57be4e5ab4664dbc96R49 – Chen Li Dec 23 '18 at 20:25
  • @max66 this is more clear: https://github.com/ericniebler/range-v3/pull/643/commits/3e3a766d92dced759559064e2ba741f150171ca3 – Chen Li Dec 23 '18 at 20:28

0 Answers0