类型分发机制实现
类型分发机制实现
“类型分发机制(Type Dispatch Mechanism)” 是一种 在编译期或运行期根据变量类型选择不同处理方式 的技术。
类型分发是一种机制,根据类型的不同,自动选择不同的函数或代码路径进行处理。
这可以是:
- 编译期分发(静态分发,static dispatch)
- 运行期分发(动态分发,dynamic dispatch)
这样一套函数:
void print(int i) { std::cout << "int: " << i << '\n'; }
void print(double d) { std::cout << "double: " << d << '\n'; }
void print(std::string s) { std::cout << "string: " << s << '\n'; }
print(42); // 选择 void print(int)
print(3.14); // 选择 void print(double)
print("hello"); // 选择 void print(std::string)
🔹 这就是 类型分发:编译器根据你传入的类型自动调用不同的函数。
1、使用 C++11 的类型萃取(type traits)+ std::enable_if + 模板函数重载,实现类型分发机制。
目的
定义多个 print_type() 函数模板,根据参数类型选择对应重载函数,打印类型信息。
实现SEINAE的常用方法
std::enable_if<条件, 类型>::type
用于启用或禁用模板函数的重载,是 C++11 中实现 SFINAE(Substitution Failure Is Not An Error) 的常用方法。
如果条件为真,则 ::type 是指定的类型(如 void),否则编译器会忽略这个重载。
整型
template<typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
print_type(T value)
std::is_integral<T>::value:判断是否是整数类型;- 比如:
int,short,long,unsigned int,char; - 如果成立,启用这个版本;
- 输出:
Integral type: xxx
兜底处理:未知类型
template <typename T>
typename std::enable_if<
!std::is_integral<T>::value &&
!std::is_floating_point<T>::value &&
!std::is_same<T, std::string>::value &&
!std::is_same<T, const char *>::value &&
!std::is_same<T, char *>::value &&
!(std::is_pointer<T>::value && !std::is_same<T, const char *>::value
&& !std::is_same<T, char *>::value) , void
>::type print_type(T value)
- 如果都不匹配,就调用这个版本;
- 输出:
Unknown type xxx
完整示例
template<typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
print_type(T value){
std::cout << "Integral type: " << value << std::endl;
}
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value, void>::type
print_type(T value){
std::cout << "Floating point type: " << value << std::endl;
}
template<typename T>
typename std::enable_if<std::is_same<T, const char*>::value ||
std::is_same<T, char *>::value>::type print_type(T value){
std::cout << "C-style string type:" << value << std::endl;
}
template<typename T>
typename std::enable_if<std::is_same<T, std::string>::value, void>::type
print_type(T value){
std::cout << "std::string type : " << value << std::endl;
}
template<typename T>
typename std::enable_if<std::is_pointer<T>::value && !std::is_same<T, const char *>::value
&& !std::is_same<T, char *>::value, void>::type
print_type(T value){
std::cout << "Pointer type " << std::endl;
}
template <typename T>
typename std::enable_if<
!std::is_integral<T>::value &&
!std::is_floating_point<T>::value &&
!std::is_same<T, std::string>::value &&
!std::is_same<T, const char *>::value &&
!std::is_same<T, char *>::value &&
!(std::is_pointer<T>::value && !std::is_same<T, const char *>::value
&& !std::is_same<T, char *>::value) , void
>::type print_type(T value){
std::cout << "Unknown type " << value << std::endl;
}
2、使用 C++20 Concepts 实现的类型分发机制
基础构件:Concepts(概念)
定义了一组 concepts(概念),用来“判断某类型是否属于某个类型类别”的。
1. 整型类型判断(Integral)
template<typename T>
concept Integral = std::is_integral_v<T>;
✅ 判断类型 T 是不是一个整型(int, short, long, …)
2、类型分发函数:cout_type(...)
定义多个重载函数,都叫 cout_type,通过 Concept 限制来区分参数类型。
整型类型分发:
void cout_type(Integral auto value){
std::cout << "Integral type: " << value << std::endl;
}
只接受整数类型:int, long, short, unsigned, size_t, …
3、未知类型 fallback:
template<typename T>
requires (!Integral<T> && !FloatingPoint<T> && !String<T> && !StdString<T> && !PointerType<T>)
void cout_type(T value){
std::cout << "Unknown type " << value << std::endl;
}
这是最后的 fallback(兜底)版本:
- 如果一个类型不满足前面任何一个 concept,就落到这个版本。
完整示例
template<typename T>
concept Integral = std::is_integral_v<T>;
template<typename T>
concept FloatingPoint = std::is_floating_point_v<T>;
template<typename T>
concept String = std::is_same_v<T, const char *> || std::is_same_v<T, char *>;
template<typename T>
concept StdString = std::is_same_v<T, std::string>;
template<typename T>
concept PointerType = std::is_pointer_v<T> && !std::is_same_v<T, char *> && !std::is_same_v<T, const char *>;
void cout_type(Integral auto value){
std::cout << "Integral type: " << value << std::endl;
}
void cout_type(FloatingPoint auto value){
std::cout << "Floating point type: " << value << std::endl;
}
void cout_type(String auto value){
std::cout << "C-style string type:" << value << std::endl;
}
void cout_type(StdString auto value){
std::cout << "std::string type : " << value << std::endl;
}
void cout_type(PointerType auto value){
std::cout << "Pointer type " << std::endl;
}
template<typename T>
requires (!Integral<T> && !FloatingPoint<T> && !String<T> && !StdString<T> && !PointerType<T>)
void cout_type(T value){
std::cout << "Unknown type " << value << std::endl;
}

浙公网安备 33010602011771号