如何创建value_type类型特征?

时间:2019-12-30 19:27:53

标签: c++ string traits value-type

我正在编写一个程序,该程序将大量处理各种类型的字符串(即std::stringstd::string_viewconst char*char[]以及各种{{1 }})。因此,我写一个可以抽象地获取通用数组状结构的值类型的特征很有趣。对于先前列出的类型,正确的返回类型应为CharT

但是,我似乎无法正确实现实现以允许泛型类型。考虑以下尝试:

char

这当然不会编译,因为并非所有类型都具有嵌套的template<class T> struct value_type{ using type = std::conditional_t< std::is_class_v<T>, typename T::value_type, std::conditional_t< std::is_pointer_v<T>, std::remove_pointer_t<T>, // etc. >; }; typedef。

有什么方法可以有效地实现此特征?

2 个答案:

答案 0 :(得分:0)

您可以使用专业化(和SFINAE):

template<class T, Enabler = void>
struct value_type;

template<class T>
struct value_type<T, std::void_t<typename T::value_type>>
{
    using type = typename T::value_type;
};

template<class T>
struct value_type<const T*>
{
    using type = T;
};

template<class T, std::size_t N>
struct value_type<const T[N]>
{
    using type = T;
};

// ...

答案 1 :(得分:0)

您可以遵循助手类模板。幸运的是,类型别名在隐式实例化过程中没有实例化:

template <class T>
struct get_value_type {
  using type = typename T::value_type;
};

template <class T>
struct value_type {
  using type = typename std::conditional_t<
      std::is_class_v<T>,
      get_value_type<T>,
      std::conditional<std::is_pointer_v<T>, std::remove_pointer_t<T>, void> 
  >::type;
};

这还需要您将第二个std::conditional_t更改为std::conditional,以便我们可以从返回的任何类型中获取::type