C++ 提供了编译期类型判断运行期类型判断两种核心方式,分别对应不同场景:

  • 编译期std::is_samestd::is_pointer 等类型萃取(模板元编程),无性能损耗
  • 运行期typeiddynamic_cast,主要用于多态类的类型判断

下面分场景给你最实用的用法和示例。

一、编译期类型判断(推荐,无运行开销)

用于编写模板、通用代码,在编译时就确定类型,不生成运行时代码。需要包含头文件:<type_traits>(C++11 及以上)

1. 判断两个类型是否完全相同

cpp

运行

#include <iostream>
#include <type_traits>  // 必须包含

int main() {
    // 判断 int 和 int 是否相同
    bool isInt = std::is_same<int, int>::value;  // true
    // 判断 int 和 double 是否相同
    bool isDiff = std::is_same<int, double>::value;  // false

    // C++17 简化写法
    bool same = std::is_same_v<int, int>;

    std::cout << std::boolalpha;  // 输出 true/false 而非 1/0
    std::cout << isInt << "\n" << isDiff << "\n";
    return 0;
}

2. 常用内置类型判断(直接用)

表格

模板 作用
is_integral<T> 判断是否为整数类型(int/char/long 等)
is_floating_point<T> 判断是否为浮点类型(float/double)
is_pointer<T> 判断是否为指针
is_array<T> 判断是否为数组
is_class<T> 判断是否为类 / 结构体
is_enum<T> 判断是否为枚举
is_const<T> 判断是否为 const 修饰

示例:

cpp

运行

int a = 10;
double b = 3.14;
int* p = &a;

std::cout << std::is_integral_v<decltype(a)> << "\n";  // true
std::cout << std::is_floating_point_v<decltype(b)> << "\n";  // true
std::cout << std::is_pointer_v<decltype(p)> << "\n";  // true

二、运行期类型判断(用于多态对象)

用于不确定对象实际类型的场景(比如基类指针指向派生类对象)。

1. typeid(获取类型信息 + 比较类型)

  • 包含头文件:<typeinfo>
  • 配合 decltype(变量) 或直接传类型
  • 仅多态类(有虚函数) 才能获取实际派生类类型

cpp

运行

#include <iostream>
#include <typeinfo>

// 基类(必须有虚函数,typeid 才能识别派生类)
class Base {
public:
    virtual ~Base() = default;
};

// 派生类
class Derived : public Base {};

int main() {
    Base* ptr = new Derived();

    // 比较类型
    if (typeid(*ptr) == typeid(Derived)) {
        std::cout << "实际类型是 Derived\n";
    }

    // 打印类型名称(不同编译器输出不同)
    std::cout << typeid(*ptr).name() << "\n";

    delete ptr;
    return 0;
}

2. dynamic_cast(安全转换 + 类型判断)

最常用的运行期类型校验

  • 转换成功返回有效指针 / 引用,失败返回 nullptr(指针)
  • 仅适用于带虚函数的多态类

cpp

运行

Base* ptr = new Derived();

// 尝试转换为 Derived*
Derived* dptr = dynamic_cast<Derived*>(ptr);
if (dptr != nullptr) {
    std::cout << "是 Derived 类型\n";
} else {
    std::cout << "不是 Derived 类型\n";
}

三、快速判断变量类型(通用写法)

decltype(变量) 获取变量类型,再配合 is_same 判断:

cpp

运行

auto x = 123;
if constexpr (std::is_same_v<decltype(x), int>) {
    std::cout << "x 是 int 类型\n";
}

if constexpr编译期条件判断,只会编译符合条件的代码。


四、核心总结

  1. 编译期判断:用 <type_traits> 里的 is_sameis_integral 等,零开销、推荐模板使用
  2. 运行期判断
    • 多态类:用 dynamic_cast(最安全)或 typeid
    • 非多态类:无法判断实际派生类型
  3. 变量类型判断decltype(变量) + is_same

更多推荐