检查给定类型是否具有内部模板重新绑定

时间:2015-07-31 10:42:09

标签: c++ templates boost template-meta-programming

我需要一个特征来检查给定类型是否有一个名为rebind的内部模板,该模板采用单个模板类型参数。类似的东西:

template <typename X>
struct has_rebind
{
    static const bool value = /* ??? */;
};

这类似于BOOST_TTI_HAS_TEMPLATE所做的,但我想在不使用Boost TTI的情况下实现该特性,我不知道该宏是如何实现的。

1 个答案:

答案 0 :(得分:4)

C ++ 11及更高版本为我们提供了丰富的选择,可以用相当简单的方式编写任意复杂的类型特征。其中一个是void_t

template <typename... >
using void_t = void;

你要做的只是写一个基本特征:

template <typename X, typename = void>
struct has_rebind : std::false_type { };

然后是部分专业化,只有满足您想要的标准时才会传递模板扣除,即Xrebind<T>。在这种情况下,类型并不重要,所以我们可以选择一个:

template <typename X>
struct has_rebind<X, void_t<typename X::template rebind<int>>>
: std::true_type { };

Demo

同一事物的另一种方法是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>;

Demo 2