【C/C++】高阶用法_笔记
1. 模板元编程(TMP)与编译时计算
(1) 类型萃取与 SFINAE
-
类型萃取(Type Traits):利用模板特化在编译时推断类型属性。
template<typename T> struct is_pointer { static constexpr bool value = false; };template<typename T> struct is_pointer<T*> { static constexpr bool value = true; };static_assert(is_pointer<int*>::value, "T must be a pointer");
-
SFINAE(Substitution Failure Is Not An Error):通过模板参数匹配失败实现条件编译。
template<typename T> auto foo(T t) -> decltype(t.serialize(), void()) { /* T 有 serialize() 方法时调用 */ }template<typename T> void foo(...) { /* 默认实现 */ }
(2) 编译时计算(constexpr 与模板)
-
constexpr 函数:在编译期执行计算。
constexpr int factorial(int n) {return (n <= 1) ? 1 : n * factorial(n - 1); } static_assert(factorial(5) == 120);
-
模板递归计算:
template<int N> struct Factorial { static constexpr int value = N * Factorial<N-1>::value; };template<> struct Factorial<0> { static constexpr int value = 1; };
2. 移动语义与完美转发
(1) 右值引用与移动语义
- 避免深拷贝:通过移动构造函数和
std::move
转移资源所有权。class BigData {BigData(BigData&& other) noexcept : ptr_(other.ptr_) { other.ptr_ = nullptr; }int* ptr_; };BigData a; BigData b = std::move(a); // 触发移动构造
(2) 完美转发(Perfect Forwarding)
- 保留参数类型:使用
std::forward
转发参数到其他函数。template<typename... Args> void wrapper(Args&&... args) {target(std::forward<Args>(args)...); // 保持参数的值类别(左值/右值) }
3. 智能指针与资源管理
(1) 所有权管理
-
std::unique_ptr
:独占所有权,不可复制,可移动。auto ptr = std::make_unique<int>(42); // 推荐替代 new
-
std::shared_ptr
:共享所有权,基于引用计数。auto ptr = std::make_shared<int>(42); // 引用计数 +1 auto ptr2 = ptr; // 引用计数 +2
-
std::weak_ptr
:打破循环引用,避免内存泄漏。std::weak_ptr<A> weak = shared_ptr_A; if (auto spt = weak.lock()) { /* 安全访问 */ }
4. 并发编程与原子操作
(1) 线程与同步
-
std::thread
:跨平台线程管理。void task() { std::cout << "Thread running\n"; } std::thread t(task); t.join();
-
互斥锁与条件变量:
std::mutex mtx; std::unique_lock<std::mutex> lock(mtx); // RAII 风格锁 std::condition_variable cv; cv.wait(lock, []{ return data_ready; }); // 条件等待
(2) 原子操作(Atomic)
- 无锁编程:保证操作的原子性。
std::atomic<int> counter{0}; counter.fetch_add(1, std::memory_order_relaxed);
5. RAII(资源获取即初始化)
- 资源自动释放:利用对象生命周期管理资源(如文件句柄、网络连接)。
class FileHandle { public:FileHandle(const char* filename) : file_(fopen(filename, "r")) {}~FileHandle() { if (file_) fclose(file_); } private:FILE* file_; };
6. 类型推导与现代语法
(1) auto
与 decltype
-
自动类型推导:
auto x = 42; // x 为 int auto& ref = x; // ref 为 int& const auto* ptr = &x; // ptr 为 const int*
-
decltype
推导表达式类型:int a = 10; decltype(a) b = a; // b 的类型为 int
(2) Lambda 表达式
- 匿名函数对象:
auto lambda = [](int x) -> int { return x * 2; }; std::vector<int> v = {1, 2, 3}; std::transform(v.begin(), v.end(), v.begin(), [](int x) { return x + 1; });
7. 元编程库与工具
(1) Boost 库
Boost.Hana
:现代 C++ 元编程库。using namespace boost::hana; auto types = tuple_t<int, double, char>; // 类型容器
(2) std::variant
与 std::visit
- 类型安全的联合体:
std::variant<int, double, std::string> v; v = 3.14; // 存储 double std::visit([](auto&& arg) { std::cout << arg; }, v); // 访问值
8. 高级调试与优化
(1) 自定义内存管理
- 重载
new
/delete
:void* operator new(size_t size) {void* p = custom_alloc(size);if (!p) throw std::bad_alloc();return p; }
(2) 内联汇编与编译器指令
- 嵌入汇编代码(需谨慎):
int add(int a, int b) {asm("addl %%ebx, %%eax;" : "=a"(a) : "a"(a), "b"(b));return a; }
应用场景示例
- 高性能计算:利用模板元编程生成优化代码,减少运行时开销。
- 游戏引擎:通过移动语义高效管理资源(纹理、模型)。
- 分布式系统:使用原子操作实现无锁数据结构(队列、哈希表)。
- 嵌入式开发:通过 RAII 管理硬件资源(GPIO、定时器)。
注意事项
- 可读性平衡:避免过度使用模板元编程导致代码晦涩。
- 异常安全:确保资源在异常发生时正确释放。
- 跨平台兼容性:注意不同编译器对特性的支持差异(如 MSVC 和 GCC)。