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

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











