最近有个要判断共享指针模板类型的需求,为此编写了该代码,之前没有说过空类型的用法,借此例子来说一下:

在主模板的声明中,允许使用一个默认的空类型,即typename = void,在偏特化模板的版本中使用了std::void_t<>这个模板,std::void_t<>这个类型的原型为

template <class... _Types>
using void_t = void;

唯一的作用就是辅助编译器进行SFINAE匹配。在std::shared_ptr中存在着一个element_type的类型,如果存在该类型就匹配偏特化版本,否则匹配主模板。

在偏特化版本中使用std::is_same这个判断两个类型是否相等的工具,使用传入的模板类型T,与该类型内的元素类型作为shared_ptr参数的类型进行判断。

template<typename T, typename = void>
struct is_shared_ptr
{
    constexpr inline static bool value = false;
};
template<typename T>
struct is_shared_ptr<T, std::void_t<typename T::element_type>>
{
    constexpr inline static bool value = std::is_same<T, std::shared_ptr<typename T::element_type>>::value;
};

除此之外还编写了移除模板类型的函数

template<typename T, typename = void>
struct remove_shared_ptr
{
    using type = T;
};
template<typename T>
struct remove_shared_ptr<T, std::void_t<typename T::element_type>>
{
    using type = T::element_type;
};