我需要一个特征来检查给定类型是否有一个名为rebind
的内部模板,该模板采用单个模板类型参数。类似的东西:
template <typename X>
struct has_rebind
{
static const bool value = /* ??? */;
};
这类似于BOOST_TTI_HAS_TEMPLATE所做的,但我想在不使用Boost TTI的情况下实现该特性,我不知道该宏是如何实现的。
答案 0 :(得分:4)
C ++ 11及更高版本为我们提供了丰富的选择,可以用相当简单的方式编写任意复杂的类型特征。其中一个是void_t
:
template <typename... >
using void_t = void;
你要做的只是写一个基本特征:
template <typename X, typename = void>
struct has_rebind : std::false_type { };
然后是部分专业化,只有满足您想要的标准时才会传递模板扣除,即X
有rebind<T>
。在这种情况下,类型并不重要,所以我们可以选择一个:
template <typename X>
struct has_rebind<X, void_t<typename X::template rebind<int>>>
: std::true_type { };
同一事物的另一种方法是Yakk's can_apply
,它带有一些样板:
namespace details {
template<class...>struct voider{using type=void;};
template<class...Ts>using void_t=typename voider<Ts...>::type;
template<template<class...>class Z, class, class...Ts>
struct can_apply:std::false_type{};
template<template<class...>class Z, class...Ts>
struct can_apply<Z, void_t<Z<Ts...>>, Ts...>:std::true_type{};
}
template<template<class...>class Z, class...Ts>
using can_apply=details::can_apply<Z,void,Ts...>;
我们可以写类似的东西:
template <typename X, typename T>
using rebind_t = typename X::template rebind<T>;
template <typename X>
using has_rebind = can_apply<rebind_t, X, int>;