c++类型判断

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

  • 编译期 :std::is_same、std::is_pointer 等类型萃取(模板元编程),无性能损耗
  • 运行期 :typeid、dynamic_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_same、is_integral 等,零开销、推荐模板使用
  2. 运行期判断 :
    • 多态类:用 dynamic_cast(最安全)或 typeid
    • 非多态类:无法判断实际派生类型
  3. 变量类型判断 :decltype(变量) + is_same
相关推荐
2601_962218617 分钟前
深入理解C++中的thread_local线程局部变量的应用
开发语言·c++
外收内放11 分钟前
Python基础语法练习题(31-33)
开发语言·python
无名猿12 分钟前
C++ lambda 捕获列表详解:值捕获、引用捕获、初始化捕获与悬垂引用
c++·现代c++·语法基础·踩坑记录
CRMEB系统商城18 分钟前
前后端技术栈全面换代!CRMEB 多商户(Java)v3.0更新预告
java·开发语言·小程序·php
2601_9628857219 分钟前
如何用 Python 画 K 线图(蜡烛图)?(mplfinance + 均线 + 成交量)
开发语言·python
事圆则缓22 分钟前
Flutter 状态管理框架对比(三):Riverpod 如何连起购物车与异步价格
开发语言·javascript·flutter
蓝宝石的傻话24 分钟前
onvif-go(mickeyzzc/onvif-go v2)完整参考手册:从建工程到写出自己的 NVR 接入
开发语言·后端·golang
Elastic 中国社区官方博客33 分钟前
使用 Lucene 搜索你的 Bean —— Elasticsearch
大数据·开发语言·人工智能·elasticsearch·搜索引擎·全文检索·lucene
Sayai1 小时前
Neo4j 内嵌模式(Embedded)实战:Java 嵌入式 vs 服务端部署的写入性能对比与 GC 调优
java·开发语言·性能优化·neo4j·图数据库
lengxuenong1 小时前
枚举例题分析
c++·算法·青少年编程