利用模板推导来判断类型是否为整数?
首先用一个非特化的模板来标记非数字的情形.
template<typename T>
struct st_integer{
static const bool value = false ;
};
下面用各种整数类型来(完全) 特化模板st_integer
, 并增加类型字段来记录具体的整数类型:
template<>
struct st_integer<int> {
static const bool value = true; // 表示传入的模板实参确实为整数类型.
using type = int;
};
template<> // 当传入模板参数为long时
struct st_integer<long> {
static const bool value = true;
using type = long;
};
template<> // 当传入模板参数为long long时
struct st_integer<long long> {
static const bool value = true;
using type = long long;
};
template<> //
struct st_integer<unsigned short> {
static const bool value = true;
using type = unsigned short;
};
template<>
struct st_integer<unsigned int> {
static const bool value = true;
using type = unsigned int;
};
template<>
struct st_integer<unsigned long> {
static const bool value = true;
using type = unsigned long;
};
template<>
struct st_integer<unsigned long long> {
static const bool value = true;
using type = unsigned long long;
};
有了st_integer
这个模板类为我们提供是否为整数?整数是什么类型? 这两个信息后, 可以进一步编写下面两个模板, 它们用来更加方便地提供这两个信息:
template<typename T>
constexpr bool is_integer = st_integer<T>::value;
这个模板变量提供了某类型是否为整数类型的信息. 要点有两个:
- 这是一个模板变量! 可以根据不同的类型创建同名的不同变量
constexpr
修饰的变量不是常量(const
) ! 它的准确含义是 编译期表达式 ! 意思是该编译期表达式的值只能在编译时被修改. 在这里这个变量的值本质上是由传入的类型决定的, 没有必要将其值的计算放在运行时. 因此加上constexpr, 让其在编译期就将值算出来. 以提高运行效率.
这个模板的作用是返回整数的具体类型.
template<typename T>
using integer_t = typename st_integer<T>::type;
需要注意的是第二个typename的作用: 用来指示 ... ::type
是个类型. 而不是变量或别的什么