这里是实现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_ {};
一个包装器,它使用 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 {};
我还问了一个问题__dependent_type
(为避免重复,我不在__dependent_type
这里放细节)
如果meta::defer
只是推迟 SFINAE 的表达式,是否可以将其替换为__dependent_type
上面的,为什么?