C++11 新特性全面总结

C++11 全新全面特性总结


核心思想:C++11 是 C++ 语言的一次革命性升级,被称为"现代C++的起点"。它引入了移动语义、智能指针、Lambda、类型推导、并发支持等大量新特性,从根本上改变了C++的编程范式,使代码更安全、更简洁、更高效。


🚀 1. 类型推导与初始化

1.1 auto 类型推导

  • 让编译器根据初始化表达式自动推导变量类型
  • 减少冗长的类型声明,提高可读性
C++ 复制代码
// ❌ C++98 繁琐写法
std::map<std::string, std::vector<int>>::iterator it = myMap.begin();

// ✅ C++11 auto 简洁写法
auto it = myMap.begin();

// auto 与 const/引用 配合
const auto& ref = someExpression;   // const 引用
auto* ptr = &someObject;            // 指针

// ⚠️ 注意:auto 不能用于函数参数(C++11),不能用于类成员变量

1.2 decltype 类型推导

  • 在不求值的情况下获取表达式的类型
  • 常用于模板编程和返回类型推导
C++ 复制代码
int x = 42;
decltype(x) y = 100;       // y 的类型是 int

// 配合 auto 用于尾置返回类型
template <typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
    return a + b;
}

// decltype 保留引用和 const 属性
const int& cr = x;
decltype(cr) z = y;         // z 的类型是 const int&

// decltype((x)) 注意双括号
decltype((x)) ref = x;      // ref 的类型是 int&(左值表达式)

1.3 统一初始化(花括号初始化)

C++ 复制代码
// 花括号 {} 可以在任何地方进行初始化
int a{5};                           // 变量
int arr[]{1, 2, 3};                 // 数组
std::vector<int> v{1, 2, 3, 4};    // 容器
std::map<std::string, int> m{{"a", 1}, {"b", 2}};  // map

// 防止窄化转换(narrowing conversion)
// int x{3.14};    // ❌ 编译错误!防止精度丢失
int y = 3.14;      // ⚠️ 仅警告,允许编译

// 类的成员初始化
struct Point {
    int x{0};       // 类内默认初始化(C++11新增)
    int y{0};
};

1.4 std::initializer_list

C++ 复制代码
#include <initializer_list>

class MyContainer {
    std::vector<int> data_;
public:
    // 支持初始化列表构造
    MyContainer(std::initializer_list<int> init) : data_(init) {}
    
    void append(std::initializer_list<int> values) {
        data_.insert(data_.end(), values.begin(), values.end());
    }
};

void example() {
    MyContainer c = {1, 2, 3, 4, 5};
    c.append({6, 7, 8});
    
    // ⚠️ 注意 vector 的构造歧义
    std::vector<int> v1(5, 3);   // 5个元素,每个值为3:{3,3,3,3,3}
    std::vector<int> v2{5, 3};   // 2个元素:{5, 3}
}

📦 2. 移动语义与右值引用

2.1 右值引用 (&&)

  • C++11 最核心的特性之一
  • 区分"可以安全窃取资源"的临时对象
C++ 复制代码
/*
 *  值类别(Value Categories)
 *  ┌──────────┬──────────────────────────────────────┐
 *  │  左值    │ 有名字、可取地址的表达式               │
 *  │ (lvalue) │ 例:变量名、*ptr、str[0]              │
 *  ├──────────┼──────────────────────────────────────┤
 *  │  右值    │ 临时的、无名的、即将销毁的表达式        │
 *  │ (rvalue) │ 例:42、x+y、std::string("hello")    │
 *  └──────────┴──────────────────────────────────────┘
 */

void process(int& x)  { std::cout << "左值引用\n"; }
void process(int&& x) { std::cout << "右值引用\n"; }

void example() {
    int a = 10;
    process(a);          // 左值引用
    process(42);         // 右值引用
    process(a + 1);      // 右值引用
}

2.2 移动构造与移动赋值

C++ 复制代码
class BigBuffer {
    int* data_;
    size_t size_;
public:
    // 构造函数
    BigBuffer(size_t n) : data_(new int[n]), size_(n) {
        std::cout << "构造: 分配 " << n << " 个int\n";
    }
    
    // 拷贝构造(深拷贝,开销大)
    BigBuffer(const BigBuffer& other) 
        : data_(new int[other.size_]), size_(other.size_) {
        std::copy(other.data_, other.data_ + size_, data_);
        std::cout << "拷贝构造: 复制 " << size_ << " 个int\n";
    }
    
    // ✅ 移动构造(窃取资源,开销极小)
    BigBuffer(BigBuffer&& other) noexcept
        : data_(other.data_), size_(other.size_) {
        other.data_ = nullptr;   // 让源对象放弃资源
        other.size_ = 0;
        std::cout << "移动构造: 零拷贝!\n";
    }
    
    // ✅ 移动赋值
    BigBuffer& operator=(BigBuffer&& other) noexcept {
        if (this != &other) {
            delete[] data_;
            data_ = other.data_;
            size_ = other.size_;
            other.data_ = nullptr;
            other.size_ = 0;
        }
        std::cout << "移动赋值: 零拷贝!\n";
        return *this;
    }
    
    ~BigBuffer() { delete[] data_; }
};

void example() {
    BigBuffer a(1000000);
    BigBuffer b = std::move(a);   // 移动构造,而非拷贝百万个int
    // 此后 a 处于"有效但不确定"的状态,不应再使用其数据
}

2.3 std::movestd::forward

C++ 复制代码
#include <utility>

// std::move:将左值无条件转为右值引用(本身不移动任何东西)
void move_example() {
    std::string s = "Hello, World!";
    std::string s2 = std::move(s);   // s 的内容被"移走"
    // s 现在为空(或处于有效但不确定状态)
    std::cout << "s2 = " << s2 << "\n";  // "Hello, World!"
}

// std::forward:完美转发,保持参数的值类别
template <typename T>
void wrapper(T&& arg) {
    // 如果传入左值 → 转发为左值
    // 如果传入右值 → 转发为右值
    target(std::forward<T>(arg));
}

// ⚠️ 常见误区
void pitfalls() {
    std::string s = "test";
    
    // ❌ move 后继续使用
    std::string s2 = std::move(s);
    // std::cout << s;  // 未定义行为(实践中通常为空,但不应依赖)
    
    // ❌ 对 const 对象 move 无效(会退化为拷贝)
    const std::string cs = "const";
    std::string s3 = std::move(cs);  // 实际调用的是拷贝构造
}

3. Lambda 表达式

3.1 基本语法

C++ 复制代码
/*
 *  Lambda 语法结构:
 *  ┌─────────────────────────────────────────────────┐
 *  │ [捕获列表](参数列表) -> 返回类型 { 函数体 }      │
 *  └─────────────────────────────────────────────────┘
 *  
 *  捕获方式:
 *  [=]      值捕获所有外部变量
 *  [&]      引用捕获所有外部变量
 *  [x]      值捕获 x
 *  [&x]     引用捕获 x
 *  [=, &x]  默认值捕获,x 引用捕获
 *  [&, x]   默认引用捕获,x 值捕获
 *  [this]   捕获当前对象指针
 */

void lambda_basics() {
    int multiplier = 3;
    
    // 最简 lambda
    auto greet = []() { std::cout << "Hello!\n"; };
    greet();
    
    // 带参数和捕获
    auto multiply = [multiplier](int x) { return x * multiplier; };
    std::cout << multiply(5) << "\n";   // 15
    
    // 引用捕获(可修改外部变量)
    int count = 0;
    auto increment = [&count]() { ++count; };
    increment();
    increment();
    std::cout << count << "\n";   // 2
    
    // mutable:允许修改值捕获的副本
    int val = 10;
    auto modifier = [val]() mutable {
        val += 5;  // 修改的是内部副本
        return val;
    };
    std::cout << modifier() << "\n";   // 15
    std::cout << val << "\n";          // 10(原始值不变)
}

3.2 Lambda 与标准算法结合

C++ 复制代码
#include <algorithm>
#include <vector>

void lambda_with_algorithms() {
    std::vector<int> nums = {1, 5, 3, 8, 2, 9, 4, 7, 6};
    
    // 自定义排序
    std::sort(nums.begin(), nums.end(), 
              [](int a, int b) { return a > b; });  // 降序
    
    // 条件计数
    int threshold = 5;
    int count = std::count_if(nums.begin(), nums.end(),
                              [threshold](int n) { return n > threshold; });
    
    // 变换
    std::vector<int> squared;
    std::transform(nums.begin(), nums.end(), std::back_inserter(squared),
                   [](int n) { return n * n; });
    
    // 遍历
    std::for_each(nums.begin(), nums.end(),
                  [](int n) { std::cout << n << " "; });
}

🛡️ 4. 智能指针

4.1 三种智能指针

C++ 复制代码
#include <memory>

/*
 *  智能指针对比:
 *  ┌──────────────┬─────────────────────────────────────┐
 *  │ unique_ptr   │ 独占所有权,不可复制,可移动           │
 *  │ shared_ptr   │ 共享所有权,引用计数                   │
 *  │ weak_ptr     │ 弱引用,不增加引用计数,打破循环引用    │
 *  └──────────────┴─────────────────────────────────────┘
 */

// unique_ptr:独占所有权
void unique_ptr_example() {
    // ✅ 推荐使用 make_unique(C++14,C++11需手动new)
    std::unique_ptr<int> p1(new int(42));
    // auto p1 = std::make_unique<int>(42);  // C++14
    
    std::cout << *p1 << "\n";   // 42
    
    // ❌ 不可复制
    // std::unique_ptr<int> p2 = p1;  // 编译错误
    
    // ✅ 可以移动
    std::unique_ptr<int> p2 = std::move(p1);
    // p1 现在为 nullptr
    
    // 管理数组
    std::unique_ptr<int[]> arr(new int[10]);
    arr[0] = 1;
    
    // 自定义删除器
    auto fileDeleter = [](FILE* fp) { 
        if (fp) fclose(fp); 
    };
    std::unique_ptr<FILE, decltype(fileDeleter)> 
        file(fopen("test.txt", "r"), fileDeleter);
}

// shared_ptr:共享所有权
void shared_ptr_example() {
    auto sp1 = std::make_shared<std::string>("Hello");
    std::cout << sp1.use_count() << "\n";   // 1
    
    {
        auto sp2 = sp1;   // 引用计数 +1
        std::cout << sp1.use_count() << "\n";   // 2
        *sp2 = "World";
    }
    // sp2 离开作用域,引用计数 -1
    std::cout << sp1.use_count() << "\n";   // 1
    std::cout << *sp1 << "\n";              // "World"
}

// weak_ptr:打破循环引用
struct Node {
    std::shared_ptr<Node> next;
    std::weak_ptr<Node> prev;      // ✅ 使用 weak_ptr 防止循环引用
    
    ~Node() { std::cout << "Node destroyed\n"; }
};

void weak_ptr_example() {
    auto n1 = std::make_shared<Node>();
    auto n2 = std::make_shared<Node>();
    n1->next = n2;
    n2->prev = n1;    // weak_ptr 不增加引用计数
    
    // 使用 weak_ptr
    if (auto locked = n2->prev.lock()) {   // 提升为 shared_ptr
        std::cout << "prev node is alive\n";
    }
}
// n1、n2 离开作用域后都能正常销毁(无循环引用)

🏗️ 5. 类相关新特性

5.1 overridefinal

C++ 复制代码
class Base {
public:
    virtual void draw() const { std::cout << "Base::draw\n"; }
    virtual void update() { std::cout << "Base::update\n"; }
    virtual ~Base() = default;
};

class Derived : public Base {
public:
    // ✅ override 明确标识覆盖,编译器会检查
    void draw() const override { std::cout << "Derived::draw\n"; }
    
    // ❌ 如果签名不匹配,编译器报错
    // void draw() override { }  // 错误!缺少 const,签名不匹配
    
    // ✅ final 禁止进一步覆盖
    void update() final { std::cout << "Derived::update\n"; }
};

// ✅ final 也可用于类,禁止继承
class FinalClass final : public Derived {
    // void update() override { }  // ❌ 错误!update 被标记为 final
};

// class SubFinal : public FinalClass { };  // ❌ 错误!FinalClass 不能被继承

5.2 defaultdelete

C++ 复制代码
class MyClass {
public:
    // ✅ 显式要求编译器生成默认实现
    MyClass() = default;
    MyClass(const MyClass&) = default;
    MyClass& operator=(const MyClass&) = default;
    ~MyClass() = default;
    
    // ✅ 显式禁止某些操作
    MyClass(MyClass&&) = delete;               // 禁止移动构造
    MyClass& operator=(MyClass&&) = delete;    // 禁止移动赋值
};

// 禁止特定类型的隐式转换
class OnlyInt {
public:
    void process(int x) { std::cout << x << "\n"; }
    void process(double) = delete;    // ❌ 禁止 double 参数
    void process(bool) = delete;      // ❌ 禁止 bool 参数
};

// 不可复制类(单例等场景)
class NonCopyable {
public:
    NonCopyable() = default;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable& operator=(const NonCopyable&) = delete;
};

5.3 委托构造函数与继承构造函数

C++ 复制代码
// 委托构造函数
class DatabaseConnection {
    std::string host_;
    int port_;
    std::string dbName_;
public:
    // 主构造函数
    DatabaseConnection(const std::string& host, int port, const std::string& db)
        : host_(host), port_(port), dbName_(db) {
        std::cout << "Connecting to " << host_ << ":" << port_ << "\n";
    }
    
    // ✅ 委托给主构造函数
    DatabaseConnection(const std::string& host)
        : DatabaseConnection(host, 3306, "default") {}
    
    DatabaseConnection()
        : DatabaseConnection("localhost") {}
};

// 继承构造函数
class Base {
public:
    Base(int x) { std::cout << "Base(" << x << ")\n"; }
    Base(int x, int y) { std::cout << "Base(" << x << "," << y << ")\n"; }
};

class Derived : public Base {
public:
    using Base::Base;   // ✅ 继承 Base 的所有构造函数
    // 不需要手动逐个转发
};

void example() {
    Derived d1(42);      // 调用 Base(int)
    Derived d2(1, 2);    // 调用 Base(int, int)
}

5.4 类内成员初始化

C++ 复制代码
class Widget {
    int width_ = 100;                        // ✅ 类内直接初始化
    int height_ = 200;
    std::string name_ = "default";
    std::vector<int> data_{1, 2, 3};         // 花括号也可以
    
public:
    Widget() = default;  // 使用类内默认值
    
    // 构造函数中的初始化列表会覆盖类内默认值
    Widget(int w, int h) : width_(w), height_(h) {}
    // name_ 和 data_ 仍使用默认值
};

🧩 6. 模板与泛型增强

6.1 可变参数模板(Variadic Templates)

C++ 复制代码
// 递归展开参数包
// 终止条件
void print() {
    std::cout << "\n";
}

// 递归模板
template <typename T, typename... Args>
void print(const T& first, const Args&... rest) {
    std::cout << first;
    if (sizeof...(rest) > 0) std::cout << ", ";
    print(rest...);   // 递归展开
}

void example() {
    print(1, "hello", 3.14, 'A');
    // 输出:1, hello, 3.14, A
}

// 完美转发工厂函数
template <typename T, typename... Args>
std::unique_ptr<T> make_unique_cpp11(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

6.2 模板别名(using

C++ 复制代码
// ✅ C++11 using 别名(比 typedef 更清晰,支持模板)
using StringVector = std::vector<std::string>;
using IntPair = std::pair<int, int>;

// ✅ 模板别名(typedef 做不到)
template <typename T>
using Vec = std::vector<T, MyAllocator<T>>;

Vec<int> myVec;   // 等价于 std::vector<int, MyAllocator<int>>

// 函数指针别名
using Callback = void(*)(int, int);
// 等价于:typedef void (*Callback)(int, int);

// std::function 别名
using Handler = std::function<void(const std::string&)>;

6.3 static_assert(编译期断言)

C++ 复制代码
// 编译期检查条件,不满足则报错
template <typename T>
class NumericContainer {
    static_assert(std::is_arithmetic<T>::value, 
                  "T must be an arithmetic type!");
    std::vector<T> data_;
};

NumericContainer<int> ok;           // ✅ 编译通过
// NumericContainer<std::string> bad; // ❌ 编译错误:T must be an arithmetic type!

// 检查平台特性
static_assert(sizeof(int) >= 4, "int must be at least 32 bits");
static_assert(sizeof(void*) == 8, "This code requires 64-bit platform");

6.4 外部模板(Extern Templates)

C++ 复制代码
// ---- header.h ----
template <typename T>
void heavyFunction(T val) { /* 复杂实现 */ }

// ---- a.cpp ----
// 在此编译单元实例化
template void heavyFunction<int>(int);

// ---- b.cpp ----
// ✅ 告诉编译器:不要在这里实例化,链接时从别处获取
extern template void heavyFunction<int>(int);
// 减少重复实例化,加快编译速度

🔧 7. 语法增强与语法糖

7.1 nullptr

C++ 复制代码
// ❌ C++98:NULL 是整数 0,可能导致歧义
void process(int x)    { std::cout << "int\n"; }
void process(char* p)  { std::cout << "pointer\n"; }

// process(NULL);       // 歧义!NULL 是 0,可能调用 int 版本

// ✅ C++11:nullptr 是专门的空指针类型
process(nullptr);       // 明确调用 pointer 版本

// nullptr 的类型是 std::nullptr_t
std::nullptr_t np = nullptr;

7.2 范围 for 循环

C++ 复制代码
void range_for_examples() {
    std::vector<int> nums = {1, 2, 3, 4, 5};
    
    // 只读遍历
    for (const auto& n : nums) {
        std::cout << n << " ";
    }
    
    // 修改元素
    for (auto& n : nums) {
        n *= 2;
    }
    
    // 遍历 initializer_list
    for (auto x : {10, 20, 30}) {
        std::cout << x << " ";
    }
    
    // 遍历 map
    std::map<std::string, int> scores = {{"Alice", 90}, {"Bob", 85}};
    for (const auto& [name, score] : scores) {   // C++17 结构化绑定
        std::cout << name << ": " << score << "\n";
    }
    // C++11 写法
    for (const auto& pair : scores) {
        std::cout << pair.first << ": " << pair.second << "\n";
    }
}

7.3 强类型枚举(enum class

C++ 复制代码
// ❌ C++98 枚举:名称泄漏到外层作用域,可隐式转为 int
enum Color { RED, GREEN, BLUE };
// int x = RED;  // 可以隐式转换

// ✅ C++11 enum class:强类型,有作用域
enum class Color : uint8_t {    // 可指定底层类型
    Red,
    Green,
    Blue
};

enum class Direction {
    Up, Down, Left, Right
};

void example() {
    Color c = Color::Red;          // 必须使用作用域
    // int x = c;                  // ❌ 编译错误,不能隐式转换
    int x = static_cast<int>(c);   // ✅ 必须显式转换
    
    // 不同 enum class 的成员名不冲突
    // Color::Up  // ❌ 错误,Up 不在 Color 中
}

7.4 constexpr(编译期常量表达式)

C++ 复制代码
// 编译期计算
constexpr int factorial(int n) {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

constexpr int val = factorial(5);   // 编译期计算为 120

// constexpr 变量
constexpr double PI = 3.14159265358979;
constexpr int MAX_SIZE = 1024;

// ⚠️ C++11 中 constexpr 函数限制较多(只能有一个 return 语句)
// C++14 放宽了限制

7.5 noexcept

C++ 复制代码
// 声明函数不会抛出异常
void safe_function() noexcept {
    // 如果抛出异常,程序直接调用 std::terminate
}

// 条件 noexcept
template <typename T>
void swap_wrapper(T& a, T& b) noexcept(noexcept(std::swap(a, b))) {
    std::swap(a, b);
}

// 移动操作应标记 noexcept(容器优化依赖于此)
class MyClass {
public:
    MyClass(MyClass&& other) noexcept { /* ... */ }
    // vector 在 resize 时,如果移动构造是 noexcept,
    // 会使用移动而非拷贝
};

7.6 原始字符串字面量与用户自定义字面量

C++ 复制代码
// 原始字符串(无需转义)
std::string path = R"(C:\Users\test\file.txt)";         // 无需 \\
std::string json = R"({"name": "Alice", "age": 30})";
std::string regex_pat = R"(\d+\.\d+)";                  // 正则更清晰

// 自定义分隔符
std::string complex_str = R"delimiter(He said "hello")delimiter";

// 用户自定义字面量
constexpr long double operator""_deg(long double deg) {
    return deg * 3.14159265358979 / 180.0;
}

constexpr unsigned long long operator""_KB(unsigned long long kb) {
    return kb * 1024;
}

void example() {
    auto angle = 90.0_deg;      // 弧度值
    auto size = 64_KB;          // 65536
}

🧵 8. 并发与多线程支持

8.1 std::thread

C++ 复制代码
#include <thread>
#include <mutex>
#include <iostream>

void worker(int id) {
    std::cout << "Thread " << id << " running\n";
}

void thread_example() {
    std::thread t1(worker, 1);
    std::thread t2(worker, 2);
    
    // Lambda 作为线程函数
    std::thread t3([]() {
        std::cout << "Lambda thread\n";
    });
    
    t1.join();    // 等待线程结束
    t2.join();
    t3.join();
    
    // detach() 可以将线程与对象分离,让线程在后台运行
}

8.2 互斥量与锁

C++ 复制代码
#include <mutex>

class ThreadSafeCounter {
    int count_ = 0;
    mutable std::mutex mtx_;
    
public:
    void increment() {
        std::lock_guard<std::mutex> lock(mtx_);  // RAII 自动加锁/解锁
        ++count_;
    }
    
    int get() const {
        std::lock_guard<std::mutex> lock(mtx_);
        return count_;
    }
};

// 避免死锁:同时锁定多个互斥量
std::mutex m1, m2;

void safe_lock() {
    std::lock(m1, m2);   // 同时锁定,避免死锁
    std::lock_guard<std::mutex> lg1(m1, std::adopt_lock);
    std::lock_guard<std::mutex> lg2(m2, std::adopt_lock);
    // 操作共享数据...
}

8.3 std::futurestd::async

C++ 复制代码
#include <future>

int compute(int x) {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    return x * x;
}

void async_example() {
    // 异步执行,返回 future
    std::future<int> result = std::async(std::launch::async, compute, 42);
    
    std::cout << "Doing other work...\n";
    
    // 获取结果(阻塞直到完成)
    int value = result.get();
    std::cout << "Result: " << value << "\n";   // 1764
    
    // promise 手动设置结果
    std::promise<std::string> prom;
    std::future<std::string> fut = prom.get_future();
    
    std::thread t([&prom]() {
        prom.set_value("Hello from thread!");
    });
    
    std::cout << fut.get() << "\n";
    t.join();
}

8.4 原子操作

C++ 复制代码
#include <atomic>

std::atomic<int> counter{0};    // 无需互斥量的线程安全计数器

void atomic_increment() {
    for (int i = 0; i < 10000; ++i) {
        counter.fetch_add(1, std::memory_order_relaxed);
        // 或者简单写为:
        // ++counter;
    }
}

void atomic_example() {
    std::thread t1(atomic_increment);
    std::thread t2(atomic_increment);
    t1.join();
    t2.join();
    std::cout << "Counter: " << counter.load() << "\n";   // 20000(精确)
}

📚 9. 新增标准库组件

9.1 std::arraystd::tuplestd::pair增强

C++ 复制代码
#include <array>
#include <tuple>

void new_containers() {
    // std::array:固定大小数组,替代C风格数组
    std::array<int, 5> arr = {1, 2, 3, 4, 5};
    arr.at(2);          // 带边界检查
    arr.size();         // 编译期已知
    arr.fill(0);        // 全部填零
    
    // std::tuple:异构元素组
    auto t = std::make_tuple(42, "hello", 3.14);
    int x = std::get<0>(t);                 // 42
    const char* s = std::get<1>(t);          // "hello"
    
    // tie 解包
    int a; std::string b; double c;
    std::tie(a, b, c) = std::make_tuple(1, "world", 2.71);
    
    // 忽略某些值
    std::tie(a, std::ignore, c) = std::make_tuple(10, "skip", 99.9);
}

9.2 无序容器(哈希表)

C++ 复制代码
#include <unordered_map>
#include <unordered_set>

void unordered_example() {
    // 平均 O(1) 的查找/插入/删除
    std::unordered_map<std::string, int> umap;
    umap["Alice"] = 90;
    umap["Bob"] = 85;
    
    // 查找
    auto it = umap.find("Alice");
    if (it != umap.end()) {
        std::cout << it->second << "\n";   // 90
    }
    
    std::unordered_set<int> uset = {1, 2, 3, 4, 5};
    std::cout << uset.count(3) << "\n";    // 1
    
    /*
     *  有序 vs 无序 对比:
     *  ┌────────────────┬──────────┬─────────────┐
     *  │                │   map    │ unordered_map│
     *  ├────────────────┼──────────┼─────────────┤
     *  │ 底层结构       │ 红黑树    │ 哈希表       │
     *  │ 查找复杂度     │ O(log n) │ 平均 O(1)   │
     *  │ 是否有序       │ ✅       │ ❌          │
     *  │ 内存开销       │ 较小     │ 较大         │
     *  └────────────────┴──────────┴─────────────┘
     */
}

9.3 std::functionstd::bind

C++ 复制代码
#include <functional>

void free_function(int x) { std::cout << "free: " << x << "\n"; }

struct Functor {
    void operator()(int x) const { std::cout << "functor: " << x << "\n"; }
    void method(int x) const { std::cout << "method: " << x << "\n"; }
};

void function_example() {
    // std::function:通用可调用对象包装器
    std::function<void(int)> fn;
    
    fn = free_function;               // 自由函数
    fn(1);
    
    fn = Functor();                   // 函数对象
    fn(2);
    
    fn = [](int x) { std::cout << "lambda: " << x << "\n"; };  // Lambda
    fn(3);
    
    // std::bind:绑定参数
    Functor obj;
    auto bound = std::bind(&Functor::method, &obj, std::placeholders::_1);
    bound(42);   // 调用 obj.method(42)
    
    // 绑定部分参数
    auto add = [](int a, int b) { return a + b; };
    auto add5 = std::bind(add, 5, std::placeholders::_1);
    std::cout << add5(3) << "\n";   // 8
}

9.4 chrono 时间库

C++ 复制代码
#include <chrono>
#include <thread>

void chrono_example() {
    // 高精度计时
    auto start = std::chrono::high_resolution_clock::now();
    
    // 模拟耗时操作
    std::this_thread::sleep_for(std::chrono::milliseconds(150));
    
    auto end = std::chrono::high_resolution_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
    
    std::cout << "Elapsed: " << elapsed.count() << " μs\n";
    
    // 时间点运算
    auto now = std::chrono::system_clock::now();
    auto tomorrow = now + std::chrono::hours(24);
}

9.5 regex 正则表达式

C++ 复制代码
#include <regex>
#include <string>

void regex_example() {
    std::string text = "Email: alice@example.com, bob@test.org";
    std::regex email_pattern(R"((\w+)@(\w+\.\w+))");
    
    // 搜索所有匹配
    auto begin = std::sregex_iterator(text.begin(), text.end(), email_pattern);
    auto end = std::sregex_iterator();
    
    for (auto it = begin; it != end; ++it) {
        std::smatch match = *it;
        std::cout << "Full: " << match[0] 
                  << ", User: " << match[1]
                  << ", Domain: " << match[2] << "\n";
    }
    
    // 替换
    std::string result = std::regex_replace(text, email_pattern, "[REDACTED]");
}

9.6 random 随机数

C++ 复制代码
#include <random>

void random_example() {
    // ✅ 现代随机数生成(替代 rand()/srand())
    std::random_device rd;                     // 硬件熵源(种子)
    std::mt19937 gen(rd());                    // Mersenne Twister 引擎
    
    std::uniform_int_distribution<> dice(1, 6);         // 均匀整数分布
    std::normal_distribution<> normal(0.0, 1.0);        // 正态分布
    std::bernoulli_distribution coin(0.5);               // 伯努利分布
    
    for (int i = 0; i < 5; ++i) {
        std::cout << "Dice: " << dice(gen)
                  << ", Normal: " << normal(gen) 
                  << ", Coin: " << coin(gen) << "\n";
    }
}

📊 10. 综合特性速查表 📊

c++ 复制代码
┌──────────────────────┬───────────────────────────────────────────────┐
│       特性分类        │                    具体特性                    │
├──────────────────────┼───────────────────────────────────────────────┤
│  类型与推导          │ auto, decltype, 尾置返回类型                    │
├──────────────────────┼───────────────────────────────────────────────┤
│  初始化              │ 统一初始化{}, initializer_list, 类内成员初始化   │
├──────────────────────┼───────────────────────────────────────────────┤
│  移动语义            │ 右值引用&&, std::move, std::forward, 移动构造   │
├──────────────────────┼───────────────────────────────────────────────┤
│  Lambda              │ 捕获列表, mutable, 与算法配合                   │
├──────────────────────┼───────────────────────────────────────────────┤
│  智能指针            │ unique_ptr, shared_ptr, weak_ptr               │
├──────────────────────┼───────────────────────────────────────────────┤
│  类增强              │ override, final, default, delete,              │
│                      │ 委托构造, 继承构造                              │
├──────────────────────┼───────────────────────────────────────────────┤
│  模板增强            │ 可变参数模板, using别名, static_assert,         │
│                      │ extern template                                │
├──────────────────────┼───────────────────────────────────────────────┤
│  语法改进            │ nullptr, 范围for, enum class, constexpr,       │
│                      │ noexcept, 原始字符串, 用户自定义字面量          │
├──────────────────────┼───────────────────────────────────────────────┤
│  并发                │ thread, mutex, lock_guard, atomic,             │
│                      │ future, async, promise, condition_variable     │
├──────────────────────┼───────────────────────────────────────────────┤
│  新库组件            │ array, tuple, unordered_map/set,               │
│                      │ function, bind, chrono, regex, random          │
└──────────────────────┴───────────────────────────────────────────────┘

💡 关键实践原则

  1. 优先使用移动语义减少不必要的拷贝
    • 实现移动构造/赋值并标记 noexcept
    • 函数返回局部对象时编译器自动应用 RVO/NRVO
  2. 用智能指针替代裸指针管理动态资源
    • 默认用 unique_ptr,需要共享时用 shared_ptr
    • weak_ptr 打破循环引用
  3. 用 Lambda 替代简单的函数对象
    • 算法配合 Lambda 代替手写循环
    • 注意捕获方式(值 vs 引用)对生命周期的影响
  4. auto 简化代码但不滥用
    • 迭代器类型、复杂模板表达式适合用 auto
    • 基本类型和需要明确语义的场景保留显式类型
  5. override/final/delete 让意图显式化
    • 编译器帮你检查错误,防止无声的 bug
  6. 用标准并发组件替代平台特定 API
    • std::thread + std::mutex + std::atomic 实现可移植并发

总结

C++11 是现代 C++ 的分水岭,从语言核心到标准库都发生了深刻变革。移动语义 解决了不必要拷贝的性能瓶颈,智能指针 消除了内存泄漏的风险,Lambda 表达式 让函数式编程成为可能,auto/decltype 减少了类型书写的负担,并发库提供了跨平台的多线程支持。

掌握 C++11 新特性不仅是技术升级,更是编程思维的转变:从手动管理资源到 RAII 自动管理,从面向过程循环到算法+Lambda 组合,从平台依赖到标准化可移植。这些特性共同构成了高效、安全、优雅的现代 C++ 编程范式的基础。

相关推荐
6Hzlia2 小时前
【Hot 100 刷题计划】 LeetCode 76. 最小覆盖子串 | C++ 滑动窗口题解
c++·算法·leetcode
像素猎人2 小时前
蓝桥杯OJ2049蓝桥勇士【动态规划】【dp[n]不是符合题意的答案,只是以an结尾的子问题的答案】
c++·算法·蓝桥杯·动态规划·区间dp
xiaoye-duck3 小时前
《算法题讲解指南:动态规划算法--子数组系列》--21.乘积最大子数组,22.乘积为正数的最长子数组
c++·算法·动态规划
计算机安禾3 小时前
【数据结构与算法】第24篇:哈夫曼树与哈夫曼编码
c语言·开发语言·数据结构·c++·算法·visual studio
郝学胜-神的一滴3 小时前
[力扣 20] 栈解千愁:有效括号序列的优雅实现与深度解析
java·数据结构·c++·算法·leetcode·职场和发展
代码改善世界3 小时前
【C++初阶】手撕C++ string类
java·开发语言·c++
君鼎3 小时前
C++14 新特性全面总结
c++
ShineWinsu3 小时前
MySQL主从延迟根因诊断法技术文章大纲
c++
tankeven3 小时前
HJ160 迷宫
c++·算法