Check if a given type has a inner template rebind

笑着哭i 提交于 2019-12-10 11:45:28

问题


I need a trait which will check if a given type has an inner template named rebind which takes a single template type parameter. Something like:

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

This is similar to what BOOST_TTI_HAS_TEMPLATE does, but I want to implement the trait without the use of Boost TTI, and I do not know how that macro is implemented.


回答1:


C++11 and up gives us a wealth of alternatives with which to write arbitrarily complex type traits in fairly simple fashion. One such is void_t:

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

All you do is write a base trait:

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

and then a partial specialization that will only pass template deduction if the criteria you want is met, namely that X has a rebind<T>. In this case, the type doesn't matter, so we can just pick one:

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

Demo


A different approach to the same thing is Yakk's can_apply, which with some boilerplate:

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...>;

We can write something similar:

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



来源:https://stackoverflow.com/questions/31744212/check-if-a-given-type-has-a-inner-template-rebind

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!