type traits 是 c++ 编译期类型元编程基础设施,基于模板特化与 SFINAE 实现,提供判断(is_)、变换(_t)和辅助(void_t)三类工具,用于静态类型探测与约束。

type traits 是 C++ 标准库中一组用于在编译期查询、判断和变换类型的模板工具,本质是基于模板特化与 SFINAE(C++17 后逐渐被 constexpr if 和 concepts 补充)实现的类型元编程基础设施。
核心作用:编译期类型信息的“探测器”
它们不生成运行时代码,而是在模板实例化过程中,通过类型检查返回编译期常量(如 std::is_integral_v)或类型别名(如 std::remove_reference_t),让编译器能据此选择不同分支或调整模板行为。
- 判断型 traits:返回
std::true_type/std::false_type,如std::is_pointer、std::is_same、std::is_move_constructible - 变换型 traits:提供新类型,如
std::decay_t、std::enable_if_t、std::common_type_t - 辅助型 traits:支持条件编译,如
std::void_t(C++17 前常用作探测表达式是否合法)
典型用法:控制模板偏特化与 SFINAE
template std::enable_if_t, int> foo(T) { return 42; }
若传入 double,std::is_integral_v 为 false,导致 std::enable_if_t<...> 无定义,该重载被从候选集中移除(SFINAE),不会报错——这是 type traits 支持泛型约束的关键机制。
立即学习“C++免费学习笔记(深入)”;
现代写法更简洁:结合 constexpr if(C++17)
避免繁琐的重载或特化,直接在函数体内分支:
template auto process(T t) { if constexpr (std::is_floating_point_v) { return t * 3.14; } else if constexpr (std::is_integral_v) { return t * 2; } else { static_assert(std::is_void_v, "unsupported type"); } }
所有分支都在编译期静态决定,未满足条件的代码不参与实例化,无运行时开销。
常用头文件与命名习惯
绝大多数定义在 。标准约定:
- 判断类模板名以
is_开头(std::is_class),对应变量模板加_v后缀(std::is_class_v) - 变换类模板名以
xxx_t结尾(std::add_const_t),等价于typename std::xxx::type - 所有 trait 都是空基类、无状态、无成员函数,仅靠
::value或::type提供结果