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

Check if a given type has a inner template rebind

我需要一个特征来检查给定类型是否有一个名为 rebind 的内部模板,它接受一个模板类型参数。类似于:

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

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

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 { };

Demo


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