(57)类 make_unsigned_t《T》 是获取数据类型 T 的无符号版本。该模板类在接着的 atomic 原子类型, _Atomic_integral_facade《T》的学习中也会用到。所以单独列出来其推导过程。
template <size_t>
struct _Make_unsigned2; // Choose make_unsigned strategy by type size
template <>
struct _Make_unsigned2<1> {
template <class>
using _Apply = unsigned char;
};
template <>
struct _Make_unsigned2<2> {
template <class>
using _Apply = unsigned short;
};
//template <bool>
//struct _Select { template <class _Ty1, class> using _Apply = _Ty1; };
//template <>
//struct _Select<false> { template <class, class _Ty2> using _Apply = _Ty2; };
template <>
struct _Make_unsigned2<4> {
template <class _Ty> // 大部分情况下 int 等同于 long。所以 此处 _Apply = unsigned long
using _Apply = typename _Select<is_same_v<_Ty, long> || is_same_v<_Ty, unsigned long>> ::
template _Apply<unsigned long, unsigned int>;
};
template <>
struct _Make_unsigned2<8> {
template <class>
using _Apply = unsigned long long;
};
template <class _Ty> // unsigned partner to cv-unqualified _Ty
using _Make_unsigned1 = typename _Make_unsigned2<sizeof(_Ty)>::template _Apply<_Ty>;
//**************************************************************************************
template <class _Ty>
struct remove_cv // remove top-level const and volatile qualifiers
{
template <template <class> class _Fn> // 模板参数还是模板
using _Apply = _Fn<_Ty>; // apply cv-qualifiers from the class template argument to _Fn<_Ty>
};
template <class _Ty>
struct remove_cv<const _Ty>
{
template <template <class> class _Fn>
using _Apply = const _Fn<_Ty>;
};
template <class _Ty>
struct remove_cv<volatile _Ty>
{
template <template <class> class _Fn>
using _Apply = volatile _Fn<_Ty>;
};
template <class _Ty>
struct remove_cv<const volatile _Ty>
{
template <template <class> class _Fn>
using _Apply = const volatile _Fn<_Ty>;
};
//**************************************************************************************
template <class _Ty> // 要求 _Ty 是整数类型且不是 bool 类型
bool _Is_nonbool_integral = is_integral_v<_Ty> && !is_same_v<remove_cv_t<_Ty>, bool>;
template <class _Ty>
struct make_unsigned // unsigned partner to _Ty
{
static_assert(_Is_nonbool_integral<_Ty> || is_enum_v<_Ty>,
"make_unsigned<T> requires that T shall be a (possibly cv-qualified) "
"integral type or enumeration but not a bool type.");
using type = typename remove_cv<_Ty>::template _Apply<_Make_unsigned1>;
// type ≈ const volatile _Make_unsigned1<_Ty>,即 保留 _Ty 的 cv 修饰符给 模板 _Make_unsigned1<T>
// 最终 type = [ const / volatile ] unsigned [ char, short, long, long long ]
};
template <class _Ty>
using make_unsigned_t = typename make_unsigned<_Ty>::type;
++ 给个测试,以验证推断:
++ 可见,模板类的泛型推导,非常类似于文本处理,而这时候,处理文本的正则表达式的源代码就起到了很大的作用。以前的大师们编写了正则表达式的强大代码,造福后人!!
(58)在分析 _Atomic_integral_facade《T》 这个 _Atomic_storage《T,size_t》 的复杂的孙子类以前, 先测试一下其静态成员函数 _Atomic_integral_facade::_Negate(4) ,结论是该函数实现了形参数据的取反运算(即返回值是形参 数据乘以 -1):
(59)
谢谢