如何创建value_type型特征?

How can I create a value_type type trait?

本文关键字:type 特征 value 何创建 创建      更新时间:2023-10-16

我正在编写一个程序,它将大量处理不同类型的字符串(即std::stringstd::string_viewconst char*char[]和不同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.
>;
};

当然,这不会编译,因为并非所有类型都有嵌套的value_typetypedef。

有没有办法有效地实现这种特质?

您可以使用专业化(和 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;
};
// ...

您可以遵从帮助程序类模板。幸运的是,类型别名不会在隐式实例化期间实例化:

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