c++泛型编程与模板_哔哩哔哩_bilibili
C++ 类型萃取(type_traits 类型萃取)
萃取 (Traits):利用模板特化(主模板 +template<>全特化 / 类偏特化),在编译期拿到类型的信息。
全部逻辑发生在编译阶段,运行时无开销,是模板元编程基石。
简单讲:给一个类型 T,萃取器告诉你:是不是指针?是不是引用?是不是 int?是不是 const?
1、最简手写萃取示例(判断是否左值引用)
cpp
#include <iostream> // 主模板:默认情况,不是左值引用 template<typename T> struct is_lref { static constexpr bool value = false; }; // template<> 全特化,专门匹配 T& 左值引用类型 template<typename T> struct is_lref<T&> { static constexpr bool value = true; }; int main() { std::cout << is_lref<int>::value << '\n'; //0 int不是左值引用 std::cout << is_lref<int&>::value << '\n'; //1 int&是左值引用 std::cout << is_lref<int&&>::value << '\n'; //0 int&&右值引用不匹配 return 0; }原理:编译器根据传入的类型,自动选择主模板 / 全特化版本。value是编译期常量。
2、标准库萃取 std::type_traits
C++11 起标准库自带大量萃取,头文件<type_traits>
表格
| 萃取器 | 作用 |
|---|---|
std::is_lvalue_reference<T>::value | 是否左值引用 |
std::is_rvalue_reference<T>::value | 是否右值引用 |
std::is_pointer<T>::value | 是否指针类型 |
std::is_const<T>::value | 是否 const 修饰 |
std::is_same<T,U>::value | T、U 是否是同一个类型 |
std::remove_reference<T>::type | 去掉引用,拿到原始类型 |
示例:
cpp
#include <iostream> #include <type_traits> int main() { using T = int&&; std::cout << std::is_rvalue_reference<T>::value << '\n'; //1 // remove_reference:剥离引用 using RawT = std::remove_reference<T>::type; std::cout << std::is_same<RawT, int>::value << '\n'; //1 return 0; }3、萃取核心用途(结合你之前左值右值引用)
场景 1:完美转发std::forward底层就是萃取
cpp
template<typename T> void func(T&& t) { // 根据T萃取原始类型,决定转左值还是右值 other(std::forward<T>(t)); }std::forward内部就是靠remove_reference萃取去掉引用,再判断类型。
场景 2:编译期分支选择(if constexpr C++17)
编译期根据萃取结果走不同代码路径,不会生成无效运行时代码
cpp
template<t