检查 class 是否等于模板实例或普通 class
Check if a class is equal to a template instance or a normal class
我有一个 integral_constant
来确定 class 是否在提供的 class 列表中:
template <typename T> using decay_t = typename std::decay<T>::type;
template <typename... Args> struct SOneOf : std::integral_constant<bool, false>
{
};
template <typename T1, typename T2, typename... Tail> struct SOneOf<T1, T2, Tail...>
: std::integral_constant<bool, SOneOf<T1, T2>::value || SOneOf<T1, Tail...>::value>
{
};
template <typename T1, typename T2> struct SOneOf<T1, T2>
: std::integral_constant<bool, std::is_same<decay_t<T1>, decay_t<T2>>::value>
{
};
template <typename T> struct SOneOf<T> : std::integral_constant<bool, false>
{
};
我也知道我可以通过 template <template <typename> class T>
.
将模板化的 classes 作为模板参数
假设我有两个 classes
template <typename T> class CClassA;
template <typename T> class CClassB;
我在一个函数中 template <typename TF> function f()
。
我如何检查 TF
(例如 int
或 CClassA<double>
)是 CClassA
、CClassB
还是 float
?
我想实现类似的目标
SOneOf<TF, CClassA, CClassB, float>::value
如果您想在函数模板中获取该信息,您可以使用偏特化:
template <bool...> struct bool_pack;
template <bool... B>
using any_true = std::integral_constant<bool,
!std::is_same<bool_pack<false, B...>, bool_pack<B..., false>>{}>;
namespace detail {
template <template <class...> class, typename>
struct IsSpec : std::false_type {};
template <template <class...> class T, typename... U>
struct IsSpec<T, T<U...>> : std::true_type {};
}
template <typename U, template <class...> class... T>
using IsSpecialization = any_true<detail::IsSpec<T, std::decay_t<U>>{}...>;
用法很简单:
static_assert( IsSpecialization<CClassB<int>, CClassA, CClassB>{}, "" );
static_assert( !IsSpecialization<void, CClassA, CClassB>{}, "" );
Demo。 float
的额外比较必须单独进行,例如通过 std:is_same
.
如果您需要基于模板的不同代码,该类型是其特化,请使用重载。
template <typename Arg>
void f( CClassA<Arg> const& obj ) { /* … */ }
template <typename Arg>
void f( CClassB<Arg> const& obj ) { /* … */ }
我有一个 integral_constant
来确定 class 是否在提供的 class 列表中:
template <typename T> using decay_t = typename std::decay<T>::type;
template <typename... Args> struct SOneOf : std::integral_constant<bool, false>
{
};
template <typename T1, typename T2, typename... Tail> struct SOneOf<T1, T2, Tail...>
: std::integral_constant<bool, SOneOf<T1, T2>::value || SOneOf<T1, Tail...>::value>
{
};
template <typename T1, typename T2> struct SOneOf<T1, T2>
: std::integral_constant<bool, std::is_same<decay_t<T1>, decay_t<T2>>::value>
{
};
template <typename T> struct SOneOf<T> : std::integral_constant<bool, false>
{
};
我也知道我可以通过 template <template <typename> class T>
.
假设我有两个 classes
template <typename T> class CClassA;
template <typename T> class CClassB;
我在一个函数中 template <typename TF> function f()
。
我如何检查 TF
(例如 int
或 CClassA<double>
)是 CClassA
、CClassB
还是 float
?
我想实现类似的目标
SOneOf<TF, CClassA, CClassB, float>::value
如果您想在函数模板中获取该信息,您可以使用偏特化:
template <bool...> struct bool_pack;
template <bool... B>
using any_true = std::integral_constant<bool,
!std::is_same<bool_pack<false, B...>, bool_pack<B..., false>>{}>;
namespace detail {
template <template <class...> class, typename>
struct IsSpec : std::false_type {};
template <template <class...> class T, typename... U>
struct IsSpec<T, T<U...>> : std::true_type {};
}
template <typename U, template <class...> class... T>
using IsSpecialization = any_true<detail::IsSpec<T, std::decay_t<U>>{}...>;
用法很简单:
static_assert( IsSpecialization<CClassB<int>, CClassA, CClassB>{}, "" );
static_assert( !IsSpecialization<void, CClassA, CClassB>{}, "" );
Demo。 float
的额外比较必须单独进行,例如通过 std:is_same
.
如果您需要基于模板的不同代码,该类型是其特化,请使用重载。
template <typename Arg>
void f( CClassA<Arg> const& obj ) { /* … */ }
template <typename Arg>
void f( CClassB<Arg> const& obj ) { /* … */ }