C++如何使用类型萃取(Type Traits)?(头文件)

16次阅读

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

C++如何使用类型萃取(Type Traits)?(头文件)

类型萃取(Type Traits) 是 C++11 引入的一套编译期元编程工具,定义在 头文件中,用于在编译时查询、判断、转换或组合类型属性。它不运行时计算,而是靠模板特化和 constexpr 推导,是实现泛型编程、SFINAE、概念约束(C++20)、以及现代库(如 STL 容器、智能指针)底层逻辑的关键基础。

判断类型属性:用 *_v 和 *_t 简化写法

C++17 起,所有标准 trait 都提供了变量模板(如 is_integral_v)和别名模板(如 remove_reference_t),比旧式 ::value::type 更简洁安全。

  • is_same_vtrueis_same_vfalse
  • is_pointer_vtrueis_pointer_vfalse
  • is_trivially_copyable_v<:string> → 可用于判断能否用 memcpy 安全复制(注意:不是所有类都满足)

类型转换:在编译期构造新类型

这类 trait 不改变语义,只提供等价但更适配的类型别名,常用于模板参数归一化或解引用处理。

  • remove_cv_tint
  • remove_reference_tint(完美转发中常用)
  • decay_tint*(数组退化为指针)
  • enable_if_t, T> → 当 T 是算术类型时才启用该重载,否则 SFINAE 掉

组合多个条件:用 conjunction / disjunction / negation

C++17 提供逻辑组合工具,替代手写嵌套 enable_if,提高可读性。

立即学习C++免费学习笔记(深入)”;

  • conjunction_v, is_signed>true 当且仅当 T 同时是整型且有符号
  • disjunction_v, is_same>> → 浮点数或复数类型
  • negation_v>trueT 不是 void

自定义 trait:基于标准 trait 构建业务逻辑

你可以封装常用判断,提升代码表达力。例如判断是否为“可序列化的 POD 类型”:

(示例:轻量级可序列化要求)

template inline constexpr bool is_simple_serializable_v =     is_trivially_copyable_v &&     is_standard_layout_v &&     !is_reference_v &&     !is_function_v;

然后在序列化函数中使用:

  • static_assert(is_simple_serializable_v, "Must be trivial and standard layout");
  • 或配合 enable_if_t 分离重载路径

text=ZqhQzanResources