类型萃取是c++11引入的编译期元编程工具,用于查询、判断、转换或组合类型属性;c++17起提供_v和_t简化写法,支持逻辑组合与自定义trait。

类型萃取(Type Traits) 是 C++11 引入的一套编译期元编程工具,定义在 <type_traits></type_traits> 头文件中,用于在编译时查询、判断、转换或组合类型属性。它不运行时计算,而是靠模板特化和 constexpr 推导,是实现泛型编程、SFINAE、概念约束(C++20)、以及现代库(如 STL 容器、智能指针)底层逻辑的关键基础。
判断类型属性:用 *_v 和 *_t 简化写法
C++17 起,所有标准 trait 都提供了变量模板(如 is_integral_v<t></t>)和别名模板(如 remove_reference_t<t></t>),比旧式 ::value 和 ::type 更简洁安全。
-
is_same_v<int int></int>→ true;is_same_v<int double></int>→ false -
is_pointer_v<int></int>→ true;is_pointer_v<int></int>→ false -
is_trivially_copyable_v<:string></:string>→ 可用于判断能否用memcpy安全复制(注意:不是所有类都满足)
类型转换:在编译期构造新类型
这类 trait 不改变语义,只提供等价但更适配的类型别名,常用于模板参数归一化或解引用处理。
-
remove_cv_t<const volatile int></const>→int -
remove_reference_t<int></int>→int(完美转发中常用) -
decay_t<int></int>→int*(数组退化为指针) -
enable_if_t<is_arithmetic_v>, T></is_arithmetic_v>→ 当T是算术类型时才启用该重载,否则 SFINAE 掉
组合多个条件:用 conjunction / disjunction / negation
C++17 提供逻辑组合工具,替代手写嵌套 enable_if,提高可读性。
立即学习“C++免费学习笔记(深入)”;
-
conjunction_v<is_integral>, is_signed<t>></t></is_integral>→ true 当且仅当T同时是整型且有符号 -
disjunction_v<is_floating_point>, is_same<t std::complex>>></t></is_floating_point>→ 浮点数或复数类型 -
negation_v<is_void>></is_void>→ true 当T不是void
自定义 trait:基于标准 trait 构建业务逻辑
你可以封装常用判断,提升代码表达力。例如判断是否为“可序列化的 POD 类型”:
(示例:轻量级可序列化要求)template<typename T>
inline constexpr bool is_simple_serializable_v =
is_trivially_copyable_v<T> &&
is_standard_layout_v<T> &&
!is_reference_v<T> &&
!is_function_v<T>;
然后在序列化函数中使用:
static_assert(is_simple_serializable_v<mystruct>, "Must be trivial and standard layout");</mystruct>- 或配合
enable_if_t分离重载路径









