类型分发机制实现

类型分发机制实现

类型分发机制(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;
}

posted @ 2025-08-07 15:49  xiaoluosibky  阅读(11)  评论(0)    收藏  举报