C++11:现代 C++ 的开端

C++11 是 C++ 历史上最重要的标准之一,它彻底改变了 C++ 的编程方式,被称为"现代 C++"的起点。

自动类型推导(auto)

auto x = 42;                        // int
auto y = 3.14;                      // double
auto z = std::vector<int>{1, 2, 3}; // std::vector<int>

// 范围 for 循环
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto& elem : vec) {
    elem *= 2;
}

Lambda 表达式

// 基本语法
auto lambda = [](int x, int y) { return x + y; };
int result = lambda(3, 4);  // 7

// 捕获变量
int a = 10;
auto captureByValue = [a](int x) { return x + a; };
auto captureByRef = [&a](int x) { a += x; };

// 捕获所有
auto captureAll = [=](int x) { return x + a; };
auto captureAllRef = [&](int x) { a += x; };

智能指针

#include <memory>

// unique_ptr:独占所有权
std::unique_ptr<int> ptr1 = std::make_unique<int>(42);
// std::unique_ptr<int> ptr2 = ptr1;  // 编译错误

// shared_ptr:共享所有权
std::shared_ptr<int> ptr3 = std::make_shared<int>(42);
std::shared_ptr<int> ptr4 = ptr3;  // 引用计数 +1

// weak_ptr:弱引用,不增加引用计数
std::weak_ptr<int> ptr5 = ptr3;

右值引用与移动语义

// 移动构造函数
class MyClass {
public:
    MyClass(MyClass&& other) noexcept
        : data_(std::move(other.data_)) {
        other.data_ = nullptr;
    }

    // 移动赋值运算符
    MyClass& operator=(MyClass&& other) noexcept {
        if (this != &other) {
            delete data_;
            data_ = std::move(other.data_);
            other.data_ = nullptr;
        }
        return *this;
    }

private:
    int* data_;
};

// std::move
std::string str1 = "Hello";
std::string str2 = std::move(str1);  // str1 现在为空

std::function 和 std::bind

#include <functional>

int add(int a, int b) { return a + b; }

// std::function:可调用对象的包装器
std::function<int(int, int)> func = add;
int result = func(3, 4);  // 7

// std::bind:绑定参数
auto add5 = std::bind(add, std::placeholders::_1, 5);
int result2 = add5(10);  // 15

// 绑定成员函数
struct Calculator {
    int multiply(int a, int b) { return a * b; }
};
Calculator calc;
auto multiplyBy2 = std::bind(&Calculator::multiply, &calc, std::placeholders::_1, 2);
int result3 = multiplyBy2(5);  // 10

std::unordered_map 和 std::unordered_set

#include <unordered_map>
#include <unordered_set>

// 哈希表
std::unordered_map<std::string, int> scores;
scores["Alice"] = 90;
scores["Bob"] = 85;

// 查找
if (scores.find("Alice") != scores.end()) {
    std::cout << "Alice's score: " << scores["Alice"] << "\n";
}

// unordered_set
std::unordered_set<int> uniqueValues = {1, 2, 2, 3, 3, 3};
// uniqueValues = {1, 2, 3}

std::tuple

#include <tuple>

// 创建 tuple
std::tuple<int, double, std::string> t{42, 3.14, "hello"};

// 获取元素
std::get<0>(t);  // 42
std::get<1>(t);  // 3.14
std::get<2>(t);  // "hello"

// 结构化绑定(C++17)
auto [id, value, name] = t;

// 连接 tuple
auto combined = std::tuple_cat(t, std::make_pair(true, 'a'));

std::chrono

#include <chrono>

// 时间点
auto now = std::chrono::system_clock::now();

//  duration
using namespace std::chrono_literals;
auto duration = 100ms;           // 100 毫秒
auto seconds = 2s;               // 2 秒
auto minutes = 5min;             // 5 分钟

// 睡眠
std::this_thread::sleep_for(500ms);

// 计时
auto start = std::chrono::high_resolution_clock::now();
// ... 执行操作
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

std::array

#include <array>

// 固定大小数组
std::array<int, 5> arr = {1, 2, 3, 4, 5};

// 访问元素
arr[0] = 10;
arr.at(1) = 20;

// 迭代
for (const auto& elem : arr) {
    std::cout << elem << " ";
}

// 大小
std::cout << "Size: " << arr.size() << "\n";  // 5

// 前后元素
std::cout << "Front: " << arr.front() << "\n";
std::cout << "Back: " << arr.back() << "\n";

// 填充
arr.fill(0);

std::forward_list

#include <forward_list>

// 单向链表
std::forward_list<int> list = {1, 2, 3, 4, 5};

// 在前面插入
list.push_front(0);

// 在指定位置后插入
auto it = list.begin();
list.insert_after(it, 100);

// 删除元素
list.pop_front();
list.erase_after(it);

// 遍历
for (const auto& elem : list) {
    std::cout << elem << " ";
}

// 检查是否为空
if (list.empty()) {
    std::cout << "List is empty\n";
}

std::random

#include <random>

// 随机数引擎
std::random_device rd;  // 硬件随机数生成器
std::mt19937 gen(rd()); // Mersenne Twister 引擎

// 均匀分布
std::uniform_int_distribution<> dis(1, 100);
int randomInt = dis(gen);  // 1-100 之间的随机整数

// 浮点数分布
std::uniform_real_distribution<> disReal(0.0, 1.0);
double randomDouble = disReal(gen);

// 正态分布
std::normal_distribution<> normal(5.0, 2.0);
double normalValue = normal(gen);

// 伯努利分布
std::bernoulli_distribution bernoulli(0.5);
bool coinFlip = bernoulli(gen);

std::regex

#include <regex>

// 正则表达式匹配
std::string text = "Hello, World! 123";
std::regex pattern(R"(\d+)");  // 匹配数字

std::smatch matches;
if (std::regex_search(text, matches, pattern)) {
    std::cout << "Found: " << matches[0] << "\n";  // 123
}

// 正则表达式替换
std::string result = std::regex_replace(text, std::regex(R"(\d+)"), "NUM");
std::cout << result << "\n";  // Hello, World! NUM

// 正则表达式迭代
std::regex word_pattern(R"(\w+)");
std::sregex_iterator it(text.begin(), text.end(), word_pattern);
std::sregex_iterator end;

for (; it != end; ++it) {
    std::cout << it->str() << "\n";
}

范围 for 循环

std::vector<int> vec = {1, 2, 3, 4, 5};

// 只读
for (const auto& elem : vec) {
    std::cout << elem << " ";
}

// 修改
for (auto& elem : vec) {
    elem *= 2;
}

// 数组
int arr[] = {1, 2, 3};
for (auto& x : arr) {
    x *= 2;
}

初始化列表

// 统一初始化
int x{42};
std::vector<int> vec{1, 2, 3, 4, 5};
std::map<std::string, int> m{
    {"apple", 1},
    {"banana", 2}
};

// 防止窄化转换
// int y{3.14};  // 编译错误

nullptr

void func(int* ptr) {}
void func(int x) {}

func(nullptr);  // 调用 func(int*)
// func(NULL);   // 可能有歧义

int* ptr = nullptr;

constexpr

constexpr int factorial(int n) {
    return n <= 1 ? 1 : n * factorial(n - 1);
}

constexpr int result = factorial(5);  // 编译期计算

类型别名

using String = std::string;
using IntVector = std::vector<int>;

// 模板别名
template<typename T>
using Vec = std::vector<T>;

Vec<int> v;  // std::vector<int>

委托构造函数

class MyClass {
public:
    MyClass(int x, int y) : x_(x), y_(y) {}

    // 委托给上面的构造函数
    MyClass(int x) : MyClass(x, 0) {}

    MyClass() : MyClass(0, 0) {}

private:
    int x_, y_;
};

override 和 final

class Base {
public:
    virtual void func() {}
    virtual void finalFunc() final {}
};

class Derived : public Base {
public:
    void func() override {}  // 明确表示重写

    // void finalFunc() override {}  // 编译错误,final 函数不能重写
};

class FinalClass final : public Base {
    // 不能被继承
};

enum class

enum class Color { Red, Green, Blue };
enum class Animal { Dog, Cat };

Color c = Color::Red;
// Color c2 = Red;  // 编译错误,需要作用域
// if (c == Animal::Dog) {}  // 编译错误,不同枚举类型不能比较

// 显式转换
int value = static_cast<int>(Color::Red);  // 0

静态断言

static_assert(sizeof(int) == 4, "int must be 4 bytes");

template<typename T>
void checkSize() {
    static_assert(sizeof(T) >= 4, "Type must be at least 4 bytes");
}

变参模板

// 打印任意数量的参数
template<typename... Args>
void print(Args... args) {
    ((std::cout << args << " "), ...);  // 折叠表达式(C++17)
    std::cout << "\n";
}

// 递归展开
template<typename T>
T sum(T first) {
    return first;
}

template<typename T, typename... Args>
T sum(T first, Args... rest) {
    return first + sum(rest...);
}

print(1, 2, 3, "hello");  // 1 2 3 hello
int total = sum(1, 2, 3, 4, 5);  // 15

常用特性总结

最常用的 C++11 特性:

  • auto 类型推导
  • Lambda 表达式
  • 智能指针(unique_ptr, shared_ptr
  • 范围 for 循环
  • nullptr
  • override 关键字
  • enum class