Z
ZHANK
模板深入

类型萃取深入

type_traits 完整使用、SFINAE 实际场景、void_t 技巧、检测成员函数

类型萃取深入

<type_traits> 是模板元编程的基础设施——编译期判断类型属性、修改类型、选择分支。

学完本章你将: 掌握 type_traits 完整用法、void_t 技巧、检测成员函数。


type_traits 速查

cpp
// 查询
std::is_integral_v<T>    // 是否整数
std::is_class_v<T>       // 是否类
std::is_same_v<T, U>    // 是否相同类型
std::is_base_of_v<B, D> // B 是 D 的基类

// 修改
std::remove_reference_t<T&>   // T
std::remove_const_t<const T>  // T
std::decay_t<const int&>      // int
std::conditional_t<B, T, F>   // B 为 true → T,否则 F

void_t 技巧 —— 检测成员

cpp
// 检测类型是否有 .size() 方法
template <typename, typename = void>
struct has_size : std::false_type {};

template <typename T>
struct has_size<T, std::void_t<decltype(std::declval<T>().size())>>
    : std::true_type {};

has_size<std::vector<int>>::value  // true
has_size<int>::value               // false

实际应用:有条件的重载

cpp
// 只有整数类型才启用
template <typename T>
std::enable_if_t<std::is_integral_v<T>, T>
safe_divide(T a, T b) {
    if (b == 0) throw std::runtime_error("除零");
    return a / b;
}

// 浮点版本——除零不抛异常,返回 inf
template <typename T>
std::enable_if_t<std::is_floating_point_v<T>, T>
safe_divide(T a, T b) {
    return a / b;
}