#include <iostream>
#include <limits>
// 模板元编程:判断类型是否为整数类型
template <typename T>
struct IsInteger {
static const bool value = false;
};
// 特化模板,判断有符号整数类型
template <>
struct IsInteger<char> {
static const bool value = true;
};
template <>
struct IsInteger<signed char> {
static const bool value = true;
};
template <>
struct IsInteger<short> {
static const bool value = true;
};
template <>
struct IsInteger<int> {
static const bool value = true;
};
template <>
struct IsInteger<long> {
static const bool value = true;
};
template <>
struct IsInteger<long long> {
static const bool value = true;
};
// 特化模板,判断无符号整数类型
template <>
struct IsInteger<unsigned char> {
static const bool value = true;
};
template <>
struct IsInteger<unsigned short> {
static const bool value = true;
};
template <>
struct IsInteger<unsigned int> {
static const bool value = true;
};
template <>
struct IsInteger<unsigned long> {
static const bool value = true;
};
template <>
struct IsInteger<unsigned long long> {
static const bool value = true;
};
// 模板元编程:根据整数类型进行不同编译期操作
template <typename T>
struct IntegerTrait {
static void operate() {
static_assert(!IsInteger<T>::value, "T must be an integer type.");
}
};
// 特化模板,对于有符号整数类型,编译期计算最大值
template <typename T>
struct IntegerTrait<T, std::enable_if_t<std::is_signed<T>::value && IsInteger<T>::value, int> = 0> {
static void operate() {
std::cout << "This is a signed integer. Max value: " << std::numeric_limits<T>::max() << std::endl;
}
};
// 特化模板,对于无符号整数类型,编译期计算最小值
template <typename T>
struct IntegerTrait<T, std::enable_if_t<std::is_unsigned<T>::value && IsInteger<T>::value, int> = 0> {
static void operate() {
std::cout << "This is an unsigned integer. Min value: " << std::numeric_limits<T>::min() << std::endl;
}
};
int main() {
IntegerTrait<int>::operate();
IntegerTrait<unsigned long>::operate();
IntegerTrait<float>::operate(); // 这会触发 static_assert 错误
return 0;
}
代码解释
- IsInteger 模板:
- 这是一个基础模板,用于判断一个类型是否为整数类型。它的默认实现
static const bool value = false;
表示对于一般类型,默认认为不是整数类型。
- 然后通过特化模板,针对所有有符号和无符号整数类型,将
value
设置为 true
,表示这些类型是整数类型。
- IntegerTrait 模板:
- 这是一个主模板,当传入的类型不是整数类型时,会触发
static_assert(!IsInteger<T>::value, "T must be an integer type.");
,提示错误。
- 第一个特化模板
IntegerTrait<T, std::enable_if_t<std::is_signed<T>::value && IsInteger<T>::value, int> = 0>
:
std::enable_if_t<std::is_signed<T>::value && IsInteger<T>::value, int>
是一个 SFINAE(Substitution Failure Is Not An Error) 工具,用于有条件地启用模板实例化。只有当 T
是有符号整数类型时,这个特化模板才会被实例化。
- 在这个特化模板的
operate
函数中,输出有符号整数类型的最大值。
- 第二个特化模板
IntegerTrait<T, std::enable_if_t<std::is_unsigned<T>::value && IsInteger<T>::value, int> = 0>
:
- 同样使用 SFINAE 工具,只有当
T
是无符号整数类型时,这个特化模板才会被实例化。
- 在这个特化模板的
operate
函数中,输出无符号整数类型的最小值。
- main 函数:
IntegerTrait<int>::operate();
调用针对有符号整数 int
的特化模板,输出 int
类型的最大值。
IntegerTrait<unsigned long>::operate();
调用针对无符号整数 unsigned long
的特化模板,输出 unsigned long
类型的最小值。
IntegerTrait<float>::operate();
尝试调用针对 float
类型的模板,由于 float
不是整数类型,会触发 static_assert
错误。