【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) autodecltype
  • 自动类型推导

    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::variantstd::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;
    }
    

应用场景示例

  1. 高性能计算:利用模板元编程生成优化代码,减少运行时开销。
  2. 游戏引擎:通过移动语义高效管理资源(纹理、模型)。
  3. 分布式系统:使用原子操作实现无锁数据结构(队列、哈希表)。
  4. 嵌入式开发:通过 RAII 管理硬件资源(GPIO、定时器)。

注意事项

  • 可读性平衡:避免过度使用模板元编程导致代码晦涩。
  • 异常安全:确保资源在异常发生时正确释放。
  • 跨平台兼容性:注意不同编译器对特性的支持差异(如 MSVC 和 GCC)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值