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 是编译期条件判断,只会编译符合条件的代码。
四、核心总结
- 编译期判断 :用
<type_traits>里的is_same、is_integral等,零开销、推荐模板使用 - 运行期判断 :
- 多态类:用
dynamic_cast(最安全)或typeid - 非多态类:无法判断实际派生类型
- 多态类:用
- 变量类型判断 :
decltype(变量) + is_same