C++高级技术详解
目录
- 模板 (Templates)
- 右值和移动语义 (Rvalue and Move Semantics)
- 定位 new (Placement new)
- 强类型 (Strong Types)
- 智能指针 (Smart Pointers)
- 容器和算法 (Containers and Algorithms)
- Lambda表达式
- 常量表达式 (constexpr)
- 多线程和并发 (Multithreading and Concurrency)
- 现代C++特性:模块、概念、协程和范围
环境配置
在Visual Studio Code中开发C++需要:
- 安装C++扩展
- 配置编译器(GCC、Clang或MSVC)
- 创建
tasks.json
和launch.json
配置文件
// tasks.json
{
"version": "2.0.0",
"tasks": [{
"type": "cppbuild",
"label": "C++ build",
"command": "g++",
"args": [
"-std=c++20",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
]
}]
}
模板 (Templates)
1.1 函数模板
函数模板允许编写通用函数,可以处理不同类型的参数。
#include <iostream>
#include <string>
// 基本函数模板
template<typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// 多参数模板
template<typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
return a + b;
}
// 可变参数模板
template<typename T>
void print(T t) {
std::cout << t << std::endl;
}
template<typename T, typename... Args>
void print(T t, Args... args) {
std::cout << t << " ";
print(args...);
}
int main() {
std::cout << max(10, 20) << std::endl; // 20
std::cout << max(10.5, 20.3) << std::endl; // 20.3
std::cout << add(10, 20.5) << std::endl; // 30.5
print("Hello", "World", 123, 45.6); // Hello World 123 45.6
return 0;
}
1.2 类模板
#include <iostream>
#include <vector>
// 基本类模板
template<typename T>
class Stack {
private:
std::vector<T> elements;
public:
void push(const T& elem) {
elements.push_back(elem);
}
T pop() {
if (elements.empty()) {
throw std::runtime_error("Stack is empty");
}
T elem = elements.back();
elements.pop_back();
return elem;
}
bool empty() const {
return elements.empty();
}
};
// 模板特化
template<>
class Stack<bool> {
private:
std::vector<unsigned char> elements;
size_t bit_count = 0;
public:
void push(bool value) {
// 位压缩实现
if (bit_count % 8 == 0) {
elements.push_back(0);
}
if (value) {
elements.back() |= (1 << (bit_count % 8));
}
bit_count++;
}
// ... 其他方法
};
// 部分特化
template<typename T>
class Stack<T*> {
// 指针类型的特殊实现
};
int main() {
Stack<int> intStack;
intStack.push(10);
intStack.push(20);
std::cout << intStack.pop() << std::endl; // 20
return 0;
}
1.3 模板元编程
#include <iostream>
// 编译时计算阶乘
template<int N>
struct Factorial {
static constexpr int value = N * Factorial<N - 1>::value;
};
template<>
struct Factorial<0> {
static constexpr int value = 1;
};
// SFINAE (Substitution Failure Is Not An Error)
template<typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
is_odd(T i) {
return i % 2 == 1;
}
// C++17 if constexpr
template<typename T>
auto process(T value) {
if constexpr (std::is_integral_v<T>) {
return value * 2;
} else if constexpr (std::is_floating_point_v<T>) {
return value / 2.0;
} else {
return value;
}
}
int main() {
std::cout << "5! = " << Factorial<5>::value << std::endl; // 120
std::cout << is_odd(5) << std::endl; // 1
std::cout << process(10) << std::endl; // 20
std::cout << process(10.0) << std::endl; // 5.0
return 0;
}
右值和移动语义
2.1 左值和右值
#include <iostream>
#include <string>
#include <vector>
#include <utility>
// 理解左值和右值
void processValue(int& x) {
std::cout << "左值引用: " << x << std::endl;
}
void processValue(int&& x) {
std::cout << "右值引用: " << x << std::endl;
}
// 万能引用
template<typename T>
void universalRef(T&& x) {
if (std::is_lvalue_reference<T>::value) {
std::cout << "接收到左值" << std::endl;
} else {
std::cout << "接收到右值" << std::endl;
}
}
int main() {
int a = 10;
processValue(a); // 左值引用: 10
processValue(20); // 右值引用: 20
processValue(std::move(a)); // 右值引用: 10
universalRef(a); // 接收到左值
universalRef(20); // 接收到右值
return 0;
}
2.2 移动构造和移动赋值
#include <iostream>
#include <cstring>
#include <algorithm>
class String {
private:
char* data;
size_t size;
public:
// 构造函数
String(const char* str = "") {
size = strlen(str);
data = new char[size + 1];
strcpy(data, str);
std::cout << "构造函数: " << data << std::endl;
}
// 拷贝构造
String(const String& other) {
size = other.size;
data = new char[size + 1];
strcpy(data, other.data);
std::cout << "拷贝构造: " << data << std::endl;
}
// 移动构造
String(String&& other) noexcept {
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
std::cout << "移动构造: " << data << std::endl;
}
// 拷贝赋值
String& operator=(const String& other) {
if (this != &other) {
delete[] data;
size = other.size;
data = new char[size + 1];
strcpy(data, other.data);
std::cout << "拷贝赋值: " << data << std::endl;
}
return *this;
}
// 移动赋值
String& operator=(String&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
std::cout << "移动赋值: " << data << std::endl;
}
return *this;
}
~String() {
delete[] data;
}
const char* c_str() const { return data ? data : ""; }
};
// 完美转发
template<typename T>
void relay(T&& arg) {
process(std::forward<T>(arg));
}
int main() {
String s1("Hello");
String s2(s1); // 拷贝构造
String s3(std::move(s1)); // 移动构造
String s4("World");
s4 = String("Temp"); // 移动赋值
std::vector<String> vec;
vec.push_back(String("Test")); // 移动构造
return 0;
}
定位 new
定位new允许在已分配的内存上构造对象。
#include <iostream>
#include <new>
#include <memory>
class MyClass {
private:
int value;
public:
MyClass(int v) : value(v) {
std::cout << "构造 MyClass: " << value << std::endl;
}
~MyClass() {
std::cout << "析构 MyClass: " << value << std::endl;
}
void print() const {
std::cout << "Value: " << value << std::endl;
}
};
// 内存池实现
template<typename T, size_t N>
class MemoryPool {
private:
alignas(T) char buffer[sizeof(T) * N];
bool used[N] = {false};
public:
T* allocate() {
for (size_t i = 0; i < N; ++i) {
if (!used[i]) {
used[i] = true;
return reinterpret_cast<T*>(&buffer[sizeof(T) * i]);
}
}
throw std::bad_alloc();
}
void deallocate(T* ptr) {
size_t index = (reinterpret_cast<char*>(ptr) - buffer) / sizeof(T);
if (index < N) {
used[index] = false;
}
}
};
int main() {
// 基本用法
char buffer[sizeof(MyClass)];
MyClass* obj = new (buffer) MyClass(42);
obj->print();
obj->~MyClass(); // 手动调用析构函数
// 使用内存池
MemoryPool<MyClass, 10> pool;
MyClass* p1 = pool.allocate();
new (p1) MyClass(100);
MyClass* p2 = pool.allocate();
new (p2) MyClass(200);
p1->print();
p2->print();
p1->~MyClass();
p2->~MyClass();
pool.deallocate(p1);
pool.deallocate(p2);
return 0;
}
强类型
强类型通过类型系统增强代码的安全性和表达力。
#include <iostream>
#include <type_traits>
// 强类型包装器
template<typename T, typename Tag>
class StrongType {
private:
T value;
public:
explicit StrongType(T val) : value(val) {}
T& get() { return value; }
const T& get() const { return value; }
// 显式转换
explicit operator T() const { return value; }
};
// 使用标签区分不同的类型
struct DistanceTag {};
struct SpeedTag {};
struct TimeTag {};
using Distance = StrongType<double, DistanceTag>;
using Speed = StrongType<double, SpeedTag>;
using Time = StrongType<double, TimeTag>;
// 类型安全的操作
Speed operator/(const Distance& d, const Time& t) {
return Speed(d.get() / t.get());
}
Distance operator*(const Speed& s, const Time& t) {
return Distance(s.get() * t.get());
}
// 枚举类(强类型枚举)
enum class Color : uint8_t {
Red = 1,
Green = 2,
Blue = 3
};
enum class Status {
Success,
Failure,
Pending
};
// 类型特征
template<typename T>
struct is_strong_type : std::false_type {};
template<typename T, typename Tag>
struct is_strong_type<StrongType<T, Tag>> : std::true_type {};
int main() {
Distance d(100.0); // 100米
Time t(10.0); // 10秒
Speed s = d / t; // 10米/秒
std::cout << "速度: " << s.get() << " m/s" << std::endl;
// 编译错误:类型不匹配
// Speed s2 = d + t;
// 枚举类使用
Color c = Color::Red;
// int colorValue = c; // 编译错误:需要显式转换
int colorValue = static_cast<int>(c);
// 类型检查
static_assert(is_strong_type<Speed>::value);
static_assert(!is_strong_type<double>::value);
return 0;
}
智能指针
5.1 unique_ptr
#include <iostream>
#include <memory>
#include <vector>
class Resource {
private:
std::string name;
public:
Resource(const std::string& n) : name(n) {
std::cout << "Resource " << name << " 创建" << std::endl;
}
~Resource() {
std::cout << "Resource " << name << " 销毁" << std::endl;
}
void use() {
std::cout << "使用 Resource " << name << std::endl;
}
};
// 自定义删除器
struct FileDeleter {
void operator()(FILE* fp) const {
if (fp) {
std::cout << "关闭文件" << std::endl;
fclose(fp);
}
}
};
// 工厂函数
std::unique_ptr<Resource> createResource(const std::string& name) {
return std::make_unique<Resource>(name);
}
int main() {
// 基本用法
{
std::unique_ptr<Resource> ptr1 = std::make_unique<Resource>("Res1");
ptr1->use();
// 转移所有权
std::unique_ptr<Resource> ptr2 = std::move(ptr1);
// ptr1 现在为空
if (!ptr1) {
std::cout << "ptr1 已经为空" << std::endl;
}
}
// 数组
std::unique_ptr<int[]> arr = std::make_unique<int[]>(10);
for (int i = 0; i < 10; ++i) {
arr[i] = i * i;
}
// 自定义删除器
std::unique_ptr<FILE, FileDeleter> file(fopen("test.txt", "w"));
if (file) {
fprintf(file.get(), "Hello, World!");
}
// 容器中使用
std::vector<std::unique_ptr<Resource>> resources;
resources.push_back(std::make_unique<Resource>("Vec1"));
resources.push_back(std::make_unique<Resource>("Vec2"));
return 0;
}
5.2 shared_ptr
#include <iostream>
#include <memory>
#include <thread>
#include <vector>
class Node {
public:
int value;
std::shared_ptr<Node> next;
std::weak_ptr<Node> parent; // 避免循环引用
Node(int val) : value(val) {
std::cout << "Node " << value << " 创建" << std::endl;
}
~Node() {
std::cout << "Node " << value << " 销毁" << std::endl;
}
};
// 多线程共享资源
void worker(std::shared_ptr<std::vector<int>> data, int id) {
std::cout << "Worker " << id << " 开始处理,引用计数: "
<< data.use_count() << std::endl;
// 模拟工作
std::this_thread::sleep_for(std::chrono::milliseconds(100));
data->push_back(id);
}
// 自定义分配器和删除器
template<typename T>
struct ArrayDeleter {
void operator()(T* p) const {
delete[] p;
}
};
int main() {
// 基本用法
{
std::shared_ptr<Node> head = std::make_shared<Node>(1);
std::shared_ptr<Node> second = std::make_shared<Node>(2);
head->next = second;
second->parent = head; // weak_ptr 避免循环引用
std::cout << "head 引用计数: " << head.use_count() << std::endl;
std::cout << "second 引用计数: " << second.use_count() << std::endl;
}
// 多线程共享
auto sharedData = std::make_shared<std::vector<int>>();
std::vector<std::thread> threads;
for (int i = 0; i < 5; ++i) {
threads.emplace_back(worker, sharedData, i);
}
for (auto& t : threads) {
t.join();
}
std::cout << "数据大小: " << sharedData->size() << std::endl;
// 别名构造函数
struct Person {
std::string name;
int age;
};
auto person = std::make_shared<Person>(Person{"Alice", 25});
std::shared_ptr<std::string> name(person, &person->name);
return 0;
}
5.3 weak_ptr
#include <iostream>
#include <memory>
#include <map>
// 缓存系统示例
template<typename Key, typename Value>
class Cache {
private:
std::map<Key, std::weak_ptr<Value>> cache;
public:
std::shared_ptr<Value> get(const Key& key) {
auto it = cache.find(key);
if (it != cache.end()) {
// 尝试获取强引用
if (auto sp = it->second.lock()) {
std::cout << "缓存命中: " << key << std::endl;
return sp;
} else {
// 对象已经被销毁,移除缓存项
cache.erase(it);
}
}
std::cout << "缓存未命中: " << key << std::endl;
return nullptr;
}
void put(const Key& key, std::shared_ptr<Value> value) {
cache[key] = value;
}
};
// 观察者模式
class Observer {
public:
virtual void update() = 0;
virtual ~Observer() = default;
};
class Subject {
private:
std::vector<std::weak_ptr<Observer>> observers;
public:
void attach(std::shared_ptr<Observer> observer) {
observers.push_back(observer);
}
void notify() {
// 清理已经失效的观察者
auto it = observers.begin();
while (it != observers.end()) {
if (auto sp = it->lock()) {
sp->update();
++it;
} else {
it = observers.erase(it);
}
}
}
};
class ConcreteObserver : public Observer {
private:
std::string name;
public:
ConcreteObserver(const std::string& n) : name(n) {}
void update() override {
std::cout << name << " 收到更新通知" << std::endl;
}
};
int main() {
// 缓存示例
Cache<std::string, std::string> cache;
{
auto data = std::make_shared<std::string>("重要数据");
cache.put("key1", data);
auto retrieved = cache.get("key1");
if (retrieved) {
std::cout << "获取到: " << *retrieved << std::endl;
}
}
// data 已经销毁
auto retrieved = cache.get("key1");
if (!retrieved) {
std::cout << "数据已经被销毁" << std::endl;
}
// 观察者模式
Subject subject;
auto obs1 = std::make_shared<ConcreteObserver>("观察者1");
auto obs2 = std::make_shared<ConcreteObserver>("观察者2");
subject.attach(obs1);
subject.attach(obs2);
subject.notify();
obs1.reset(); // 销毁观察者1
std::cout << "\n销毁观察者1后:" << std::endl;
subject.notify();
return 0;
}
容器和算法
6.1 STL容器
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>
#include <unordered_map>
#include <array>
#include <forward_list>
#include <queue>
#include <stack>
// 自定义比较器
struct Person {
std::string name;
int age;
bool operator<(const Person& other) const {
return age < other.age;
}
};
// 自定义哈希函数
struct PersonHash {
size_t operator()(const Person& p) const {
return std::hash<std::string>()(p.name) ^ std::hash<int>()(p.age);
}
};
struct PersonEqual {
bool operator()(const Person& a, const Person& b) const {
return a.name == b.name && a.age == b.age;
}
};
int main() {
// 序列容器
std::vector<int> vec = {1, 2, 3, 4, 5};
vec.push_back(6);
vec.emplace_back(7); // 原地构造
std::deque<int> deq = {10, 20, 30};
deq.push_front(5);
deq.push_back(40);
std::list<int> lst = {100, 200, 300};
lst.splice(lst.begin(), vec); // 移动元素
// 关联容器
std::set<Person> people = {
{"Alice", 25},
{"Bob", 30},
{"Charlie", 20}
};
std::map<std::string, int> scores = {
{"Alice", 95},
{"Bob", 87},
{"Charlie", 92}
};
// 无序容器
std::unordered_map<Person, std::string, PersonHash, PersonEqual> info;
info[{"Alice", 25}] = "Engineer";
info[{"Bob", 30}] = "Manager";
// 容器适配器
std::priority_queue<int> pq;
pq.push(10);
pq.push(30);
pq.push(20);
while (!pq.empty()) {
std::cout << pq.top() << " "; // 30 20 10
pq.pop();
}
std::cout << std::endl;
// C++11 array
std::array<int, 5> arr = {1, 2, 3, 4, 5};
std::cout << "Array size: " << arr.size() << std::endl;
return 0;
}
6.2 STL算法
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <functional>
#include <iterator>
#include <random>
int main() {
std::vector<int> vec = {5, 2, 8, 1, 9, 3, 7, 4, 6};
// 排序算法
std::sort(vec.begin(), vec.end());
std::cout << "排序后: ";
std::copy(vec.begin(), vec.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// 部分排序
std::partial_sort(vec.begin(), vec.begin() + 3, vec.end(),
std::greater<int>());
std::cout << "前3个最大值: ";
std::copy(vec.begin(), vec.begin() + 3,
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// 查找算法
auto it = std::find(vec.begin(), vec.end(), 5);
if (it != vec.end()) {
std::cout << "找到5在位置: " << std::distance(vec.begin(), it) << std::endl;
}
// 二分查找(需要有序)
std::sort(vec.begin(), vec.end());
bool found = std::binary_search(vec.begin(), vec.end(), 5);
std::cout << "二分查找5: " << (found ? "找到" : "未找到") << std::endl;
// 变换算法
std::vector<int> squared;
std::transform(vec.begin(), vec.end(), std::back_inserter(squared),
[](int x) { return x * x; });
// 累积算法
int sum = std::accumulate(vec.begin(), vec.end(), 0);
int product = std::accumulate(vec.begin(), vec.end(), 1,
std::multiplies<int>());
std::cout << "和: " << sum << ", 积: " << product << std::endl;
// 分区算法
auto pivot = std::partition(vec.begin(), vec.end(),
[](int x) { return x % 2 == 0; });
std::cout << "偶数: ";
std::copy(vec.begin(), pivot, std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n奇数: ";
std::copy(pivot, vec.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// 排列组合
std::vector<int> perm = {1, 2, 3};
do {
std::copy(perm.begin(), perm.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
} while (std::next_permutation(perm.begin(), perm.end()));
// 随机算法
std::random_device rd;
std::mt19937 gen(rd());
std::shuffle(vec.begin(), vec.end(), gen);
return 0;
}
6.3 自定义迭代器
#include <iostream>
#include <iterator>
#include <algorithm>
template<typename T>
class CircularBuffer {
private:
T* buffer;
size_t capacity;
size_t size;
size_t head;
public:
class iterator {
private:
T* ptr;
T* begin;
T* end;
public:
using iterator_category = std::forward_iterator_tag;
using value_type = T;
using difference_type = std::ptrdiff_t;
using pointer = T*;
using reference = T&;
iterator(T* p, T* b, T* e) : ptr(p), begin(b), end(e) {}
reference operator*() { return *ptr; }
pointer operator->() { return ptr; }
iterator& operator++() {
ptr++;
if (ptr == end) ptr = begin;
return *this;
}
iterator operator++(int) {
iterator tmp = *this;
++(*this);
return tmp;
}
bool operator==(const iterator& other) const {
return ptr == other.ptr;
}
bool operator!=(const iterator& other) const {
return !(*this == other);
}
};
CircularBuffer(size_t cap) : capacity(cap), size(0), head(0) {
buffer = new T[capacity];
}
~CircularBuffer() {
delete[] buffer;
}
void push(const T& value) {
buffer[(head + size) % capacity] = value;
if (size < capacity) {
size++;
} else {
head = (head + 1) % capacity;
}
}
iterator begin() {
return iterator(&buffer[head], buffer, buffer + capacity);
}
iterator end() {
return iterator(&buffer[(head + size) % capacity],
buffer, buffer + capacity);
}
};
int main() {
CircularBuffer<int> cb(5);
for (int i = 0; i < 8; ++i) {
cb.push(i);
}
std::cout << "循环缓冲区内容: ";
for (auto it = cb.begin(); it != cb.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 使用STL算法
auto minmax = std::minmax_element(cb.begin(), cb.end());
std::cout << "最小值: " << *minmax.first
<< ", 最大值: " << *minmax.second << std::endl;
return 0;
}
Lambda表达式
7.1 基础Lambda
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
int main() {
// 基本语法
auto simple = []() { std::cout << "Hello Lambda!" << std::endl; };
simple();
// 带参数
auto add = [](int a, int b) { return a + b; };
std::cout << "3 + 4 = " << add(3, 4) << std::endl;
// 捕获列表
int x = 10;
int y = 20;
// 值捕获
auto captureByValue = [x, y]() {
std::cout << "x = " << x << ", y = " << y << std::endl;
};
// 引用捕获
auto captureByRef = [&x, &y]() {
x++; y++;
std::cout << "x = " << x << ", y = " << y << std::endl;
};
// 混合捕获
auto mixedCapture = [x, &y]() {
// x++; // 错误:值捕获是只读的
y++; // 可以修改引用捕获的变量
};
// 捕获所有
auto captureAll = [=]() {
std::cout << x + y << std::endl;
};
auto captureAllRef = [&]() {
x++; y++;
};
// mutable lambda
auto mutableLambda = [x]() mutable {
x++; // 现在可以修改值捕获的副本
return x;
};
std::cout << "mutable结果: " << mutableLambda() << std::endl;
std::cout << "原始x: " << x << std::endl; // x未改变
// 返回类型推导
auto divide = [](double a, double b) -> double {
return a / b;
};
// 泛型lambda (C++14)
auto genericAdd = [](auto a, auto b) {
return a + b;
};
std::cout << genericAdd(3, 4) << std::endl; // int
std::cout << genericAdd(3.5, 4.5) << std::endl; // double
std::cout << genericAdd(std::string("Hello"),
std::string(" World")) << std::endl; // string
return 0;
}
7.2 高级Lambda用法
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <memory>
// 递归lambda
auto factorial = [](auto& self, int n) -> int {
return n <= 1 ? 1 : n * self(self, n - 1);
};
// 使用std::function实现递归
std::function<int(int)> fib = [&](int n) {
return n <= 1 ? n : fib(n - 1) + fib(n - 2);
};
// Lambda作为模板参数
template<typename Func>
void repeat(int n, Func f) {
for (int i = 0; i < n; ++i) {
f(i);
}
}
// 返回lambda的函数
auto makeMultiplier(int factor) {
return [factor](int x) { return x * factor; };
}
// 状态lambda
auto makeCounter() {
return [count = 0]() mutable {
return ++count;
};
}
// 初始化捕获 (C++14)
auto makeUniqueCapture() {
return [ptr = std::make_unique<int>(42)]() {
return *ptr;
};
}
int main() {
// 使用递归lambda
std::cout << "5! = " << factorial(factorial, 5) << std::endl;
std::cout << "fib(10) = " << fib(10) << std::endl;
// Lambda与STL
std::vector<int> vec = {5, 2, 8, 1, 9, 3, 7, 4, 6};
// 排序
std::sort(vec.begin(), vec.end(),
[](int a, int b) { return a > b; });
// 查找
auto it = std::find_if(vec.begin(), vec.end(),
[](int x) { return x > 5; });
// 计数
int count = std::count_if(vec.begin(), vec.end(),
[](int x) { return x % 2 == 0; });
std::cout << "偶数个数: " << count << std::endl;
// 变换
std::vector<int> squared;
std::transform(vec.begin(), vec.end(), std::back_inserter(squared),
[](int x) { return x * x; });
// 使用lambda工厂
auto times3 = makeMultiplier(3);
auto times5 = makeMultiplier(5);
std::cout << "4 * 3 = " << times3(4) << std::endl;
std::cout << "4 * 5 = " << times5(4) << std::endl;
// 状态lambda
auto counter1 = makeCounter();
auto counter2 = makeCounter();
std::cout << "Counter1: " << counter1() << ", " << counter1() << std::endl;
std::cout << "Counter2: " << counter2() << ", " << counter2() << std::endl;
// 模板中使用
repeat(5, [](int i) {
std::cout << "Iteration " << i << std::endl;
});
// IIFE (Immediately Invoked Function Expression)
int result = [](int x, int y) {
return x + y;
}(10, 20);
std::cout << "IIFE结果: " << result << std::endl;
return 0;
}
7.3 Lambda与并发
#include <iostream>
#include <thread>
#include <vector>
#include <future>
#include <algorithm>
#include <numeric>
int main() {
// Lambda与线程
std::vector<std::thread> threads;
for (int i = 0; i < 5; ++i) {
threads.emplace_back([i]() {
std::cout << "线程 " << i << " 运行中\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
});
}
for (auto& t : threads) {
t.join();
}
// Lambda与async
std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto sum_part = [](const std::vector<int>& v, size_t start, size_t end) {
return std::accumulate(v.begin() + start, v.begin() + end, 0);
};
size_t mid = data.size() / 2;
auto future1 = std::async(std::launch::async, sum_part,
std::ref(data), 0, mid);
auto future2 = std::async(std::launch::async, sum_part,
std::ref(data), mid, data.size());
int total = future1.get() + future2.get();
std::cout << "并行求和结果: " << total << std::endl;
// 并行算法与lambda
std::vector<int> vec(1000000);
std::iota(vec.begin(), vec.end(), 1);
auto start = std::chrono::high_resolution_clock::now();
// 并行版本
int sum = std::reduce(std::execution::par, vec.begin(), vec.end(), 0,
[](int a, int b) { return a + b; });
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << "并行求和: " << sum << " 用时: " << duration.count() << "μs" << std::endl;
return 0;
}
常量表达式
8.1 constexpr基础
#include <iostream>
#include <array>
#include <type_traits>
// constexpr变量
constexpr int square(int x) {
return x * x;
}
// constexpr递归
constexpr int factorial(int n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}
// constexpr类
class Point {
private:
double x_, y_;
public:
constexpr Point(double x, double y) : x_(x), y_(y) {}
constexpr double x() const { return x_; }
constexpr double y() const { return y_; }
constexpr Point move(double dx, double dy) const {
return Point(x_ + dx, y_ + dy);
}
constexpr double distance() const {
return x_ * x_ + y_ * y_; // 简化版,实际应该开方
}
};
// constexpr if (C++17)
template<typename T>
constexpr auto getValue(T t) {
if constexpr (std::is_pointer_v<T>) {
return *t;
} else {
return t;
}
}
// 编译时字符串
template<size_t N>
struct ConstString {
char data[N];
constexpr ConstString(const char (&str)[N]) {
for (size_t i = 0; i < N; ++i) {
data[i] = str[i];
}
}
};
// 编译时排序
template<typename T, size_t N>
constexpr std::array<T, N> sort(std::array<T, N> arr) {
for (size_t i = 0; i < N - 1; ++i) {
for (size_t j = 0; j < N - i - 1; ++j) {
if (arr[j] > arr[j + 1]) {
T temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
int main() {
// 编译时计算
constexpr int val = square(5);
constexpr int fact = factorial(5);
// 用作数组大小
int arr[square(4)];
// constexpr对象
constexpr Point p1(3.0, 4.0);
constexpr Point p2 = p1.move(1.0, 2.0);
constexpr double dist = p2.distance();
// 编译时数组
constexpr std::array<int, 5> unsorted = {5, 2, 8, 1, 9};
constexpr auto sorted = sort(unsorted);
for (auto val : sorted) {
std::cout << val << " ";
}
std::cout << std::endl;
// constexpr if使用
int x = 10;
int* px = &x;
std::cout << getValue(x) << std::endl; // 10
std::cout << getValue(px) << std::endl; // 10
// 静态断言
static_assert(square(5) == 25, "Square计算错误");
static_assert(factorial(5) == 120, "Factorial计算错误");
return 0;
}
8.2 constexpr与模板元编程
#include <iostream>
#include <utility>
#include <type_traits>
// 编译时斐波那契
template<int N>
struct Fibonacci {
static constexpr int value = Fibonacci<N-1>::value + Fibonacci<N-2>::value;
};
template<>
struct Fibonacci<0> {
static constexpr int value = 0;
};
template<>
struct Fibonacci<1> {
static constexpr int value = 1;
};
// constexpr版本
constexpr int fib(int n) {
return n <= 1 ? n : fib(n - 1) + fib(n - 2);
}
// 编译时类型选择
template<bool B, typename T, typename F>
struct conditional {
using type = T;
};
template<typename T, typename F>
struct conditional<false, T, F> {
using type = F;
};
// constexpr实现
template<bool B, typename T, typename F>
constexpr auto conditional_v(T t, F f) {
if constexpr (B) {
return t;
} else {
return f;
}
}
// 编译时循环
template<size_t... Is>
constexpr auto make_index_array(std::index_sequence<Is...>) {
return std::array<size_t, sizeof...(Is)>{Is...};
}
template<size_t N>
constexpr auto make_index_array() {
return make_index_array(std::make_index_sequence<N>{});
}
// 编译时字符串哈希
constexpr size_t hash(const char* str) {
size_t h = 0;
for (size_t i = 0; str[i] != '\0'; ++i) {
h = h * 31 + str[i];
}
return h;
}
// 编译时switch
template<size_t N>
constexpr auto compile_time_switch(size_t i) {
if constexpr (N == 0) {
return "Zero";
} else if constexpr (N == 1) {
return "One";
} else if constexpr (N == 2) {
return "Two";
} else {
return "Other";
}
}
int main() {
// 比较模板元编程和constexpr
constexpr int fib10_tmp = Fibonacci<10>::value;
constexpr int fib10_cxp = fib(10);
std::cout << "模板: " << fib10_tmp << std::endl;
std::cout << "constexpr: " << fib10_cxp << std::endl;
// 编译时数组生成
constexpr auto indices = make_index_array<10>();
for (auto i : indices) {
std::cout << i << " ";
}
std::cout << std::endl;
// 编译时字符串哈希
constexpr size_t h1 = hash("Hello");
constexpr size_t h2 = hash("World");
switch (hash("Hello")) {
case h1:
std::cout << "匹配 Hello" << std::endl;
break;
case h2:
std::cout << "匹配 World" << std::endl;
break;
}
// constexpr lambda (C++17)
constexpr auto square_lambda = [](int x) constexpr {
return x * x;
};
constexpr int squared = square_lambda(5);
std::cout << "5的平方: " << squared << std::endl;
return 0;
}
多线程和并发
9.1 线程基础
#include <iostream>
#include <thread>
#include <vector>
#include <chrono>
#include <mutex>
// 全局互斥锁
std::mutex cout_mutex;
// 线程安全打印
void safe_print(const std::string& msg) {
std::lock_guard<std::mutex> lock(cout_mutex);
std::cout << msg << std::endl;
}
// 工作函数
void worker(int id, int iterations) {
for (int i = 0; i < iterations; ++i) {
safe_print("线程 " + std::to_string(id) +
" 迭代 " + std::to_string(i));
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
// 线程局部存储
thread_local int tls_value = 0;
void tls_demo(int id) {
tls_value = id;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
safe_print("线程 " + std::to_string(id) +
" TLS值: " + std::to_string(tls_value));
}
// RAII线程包装
class JoinThread {
private:
std::thread t;
public:
template<typename... Args>
explicit JoinThread(Args&&... args)
: t(std::forward<Args>(args)...) {}
~JoinThread() {
if (t.joinable()) {
t.join();
}
}
JoinThread(JoinThread&&) = default;
JoinThread& operator=(JoinThread&&) = default;
std::thread& get() { return t; }
};
int main() {
// 基本线程创建
std::thread t1([]() {
std::cout << "Hello from thread!" << std::endl;
});
t1.join();
// 带参数的线程
std::thread t2(worker, 1, 3);
std::thread t3(worker, 2, 3);
t2.join();
t3.join();
// 获取硬件并发数
unsigned int n = std::thread::hardware_concurrency();
std::cout << "硬件并发数: " << n << std::endl;
// 线程ID
std::thread t4([]() {
std::cout << "线程ID: " << std::this_thread::get_id() << std::endl;
});
t4.join();
// 线程局部存储
std::vector<std::thread> threads;
for (int i = 0; i < 5; ++i) {
threads.emplace_back(tls_demo, i);
}
for (auto& t : threads) {
t.join();
}
// 使用RAII包装
{
JoinThread jt([]() {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "RAII线程完成" << std::endl;
});
// 自动join
}
return 0;
}
9.2 同步原语
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <atomic>
#include <shared_mutex>
// 线程安全队列
template<typename T>
class ThreadSafeQueue {
private:
mutable std::mutex mut;
std::queue<T> data_queue;
std::condition_variable data_cond;
public:
void push(T value) {
{
std::lock_guard<std::mutex> lk(mut);
data_queue.push(std::move(value));
}
data_cond.notify_one();
}
T pop() {
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this] { return !data_queue.empty(); });
T value = std::move(data_queue.front());
data_queue.pop();
return value;
}
bool try_pop(T& value) {
std::lock_guard<std::mutex> lk(mut);
if (data_queue.empty()) {
return false;
}
value = std::move(data_queue.front());
data_queue.pop();
return true;
}
};
// 读写锁示例
class SharedData {
private:
mutable std::shared_mutex mutex_;
std::vector<int> data_;
public:
void write(int value) {
std::unique_lock lock(mutex_);
data_.push_back(value);
}
std::vector<int> read() const {
std::shared_lock lock(mutex_);
return data_;
}
};
// 递归锁
class RecursiveCounter {
private:
mutable std::recursive_mutex mutex_;
int count_ = 0;
public:
void increment() {
std::lock_guard<std::recursive_mutex> lock(mutex_);
++count_;
}
void add(int n) {
std::lock_guard<std::recursive_mutex> lock(mutex_);
for (int i = 0; i < n; ++i) {
increment(); // 递归调用,需要递归锁
}
}
int get() const {
std::lock_guard<std::recursive_mutex> lock(mutex_);
return count_;
}
};
// 原子操作
class AtomicCounter {
private:
std::atomic<int> count_{0};
public:
void increment() {
count_.fetch_add(1, std::memory_order_relaxed);
}
int get() const {
return count_.load(std::memory_order_relaxed);
}
void reset() {
count_.store(0, std::memory_order_relaxed);
}
};
// 自旋锁
class SpinLock {
private:
std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:
void lock() {
while (flag.test_and_set(std::memory_order_acquire)) {
// 自旋等待
}
}
void unlock() {
flag.clear(std::memory_order_release);
}
};
// 生产者-消费者模型
void producer(ThreadSafeQueue<int>& queue, int id) {
for (int i = 0; i < 5; ++i) {
queue.push(id * 100 + i);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void consumer(ThreadSafeQueue<int>& queue, int id) {
for (int i = 0; i < 5; ++i) {
int value = queue.pop();
std::cout << "消费者 " << id << " 获取: " << value << std::endl;
}
}
int main() {
// 测试线程安全队列
ThreadSafeQueue<int> queue;
std::thread prod1(producer, std::ref(queue), 1);
std::thread prod2(producer, std::ref(queue), 2);
std::thread cons1(consumer, std::ref(queue), 1);
std::thread cons2(consumer, std::ref(queue), 2);
prod1.join();
prod2.join();
cons1.join();
cons2.join();
// 测试原子计数器
AtomicCounter counter;
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i) {
threads.emplace_back([&counter]() {
for (int j = 0; j < 1000; ++j) {
counter.increment();
}
});
}
for (auto& t : threads) {
t.join();
}
std::cout << "原子计数器值: " << counter.get() << std::endl;
// 避免死锁
std::mutex m1, m2;
std::thread t1([&]() {
std::scoped_lock lock(m1, m2); // C++17
std::cout << "线程1获取两个锁" << std::endl;
});
std::thread t2([&]() {
std::scoped_lock lock(m2, m1); // 顺序不同但不会死锁
std::cout << "线程2获取两个锁" << std::endl;
});
t1.join();
t2.join();
return 0;
}
9.3 异步编程
#include <iostream>
#include <future>
#include <vector>
#include <numeric>
#include <chrono>
#include <exception>
// 异步任务
int compute(int x) {
std::this_thread::sleep_for(std::chrono::seconds(1));
if (x < 0) {
throw std::runtime_error("负数输入");
}
return x * x;
}
// Promise和Future
void producer_promise(std::promise<int> prom) {
try {
// 模拟工作
std::this_thread::sleep_for(std::chrono::seconds(1));
prom.set_value(42);
} catch (...) {
prom.set_exception(std::current_exception());
}
}
// Packaged task
class TaskManager {
private:
std::vector<std::packaged_task<int()>> tasks;
std::vector<std::future<int>> futures;
public:
void add_task(std::packaged_task<int()> task) {
futures.push_back(task.get_future());
tasks.push_back(std::move(task));
}
void run_all() {
for (auto& task : tasks) {
std::thread(std::move(task)).detach();
}
}
std::vector<int> get_results() {
std::vector<int> results;
for (auto& fut : futures) {
results.push_back(fut.get());
}
return results;
}
};
// 并行算法实现
template<typename Iterator, typename T>
T parallel_accumulate(Iterator first, Iterator last, T init) {
const size_t length = std::distance(first, last);
if (length < 1000) {
return std::accumulate(first, last, init);
}
const size_t num_threads = std::thread::hardware_concurrency();
const size_t block_size = length / num_threads;
std::vector<std::future<T>> futures;
Iterator block_start = first;
for (size_t i = 0; i < num_threads - 1; ++i) {
Iterator block_end = block_start;
std::advance(block_end, block_size);
futures.push_back(
std::async(std::launch::async,
[block_start, block_end, init]() {
return std::accumulate(block_start, block_end, init);
})
);
block_start = block_end;
}
// 最后一个块
T last_result = std::accumulate(block_start, last, init);
// 收集结果
T result = init;
for (auto& fut : futures) {
result += fut.get();
}
return result + last_result;
}
// 异步任务链
std::future<int> create_async_chain() {
return std::async(std::launch::async, []() {
return 10;
}).then([](std::future<int> f) { // C++20 特性
return f.get() * 2;
}).then([](std::future<int> f) {
return f.get() + 5;
});
}
int main() {
// std::async基本用法
auto future1 = std::async(std::launch::async, compute, 5);
auto future2 = std::async(std::launch::deferred, compute, 10);
std::cout << "异步结果1: " << future1.get() << std::endl;
std::cout << "延迟结果2: " << future2.get() << std::endl;
// 异常处理
auto future3 = std::async(std::launch::async, compute, -1);
try {
std::cout << future3.get() << std::endl;
} catch (const std::exception& e) {
std::cout << "捕获异常: " << e.what() << std::endl;
}
// Promise和Future
std::promise<int> prom;
std::future<int> fut = prom.get_future();
std::thread t(producer_promise, std::move(prom));
std::cout << "Promise结果: " << fut.get() << std::endl;
t.join();
// Shared future
std::promise<int> prom2;
std::shared_future<int> shared_fut = prom2.get_future().share();
auto waiter = [shared_fut](int id) {
std::cout << "线程 " << id << " 等待结果: "
<< shared_fut.get() << std::endl;
};
std::thread t1(waiter, 1);
std::thread t2(waiter, 2);
std::thread t3(waiter, 3);
prom2.set_value(100);
t1.join();
t2.join();
t3.join();
// 并行累加
std::vector<int> vec(10000000);
std::iota(vec.begin(), vec.end(), 1);
auto start = std::chrono::high_resolution_clock::now();
long long sum = parallel_accumulate(vec.begin(), vec.end(), 0LL);
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "并行累加结果: " << sum
<< " 用时: " << duration.count() << "ms" << std::endl;
return 0;
}
现代C++特性
10.1 模块 (C++20)
// math.ixx - 模块接口文件
export module math;
import <iostream>;
import <cmath>;
export namespace math {
double add(double a, double b) {
return a + b;
}
double multiply(double a, double b) {
return a * b;
}
class Calculator {
private:
double result = 0;
public:
void add(double x) { result += x; }
void multiply(double x) { result *= x; }
double get_result() const { return result; }
void reset() { result = 0; }
};
}
// 模块实现单元
module math;
// 私有实现细节
namespace detail {
void log_operation(const std::string& op) {
std::cout << "执行操作: " << op << std::endl;
}
}
// main.cpp - 使用模块
import math;
import <iostream>;
int main() {
std::cout << "5 + 3 = " << math::add(5, 3) << std::endl;
std::cout << "5 * 3 = " << math::multiply(5, 3) << std::endl;
math::Calculator calc;
calc.add(10);
calc.multiply(2);
std::cout << "结果: " << calc.get_result() << std::endl;
return 0;
}
10.2 概念 (C++20)
#include <iostream>
#include <concepts>
#include <vector>
#include <list>
#include <type_traits>
// 基本概念定义
template<typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;
template<typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
template<typename T>
concept Container = requires(T t) {
typename T::value_type;
typename T::size_type;
typename T::iterator;
{ t.size() } -> std::convertible_to<typename T::size_type>;
{ t.begin() } -> std::same_as<typename T::iterator>;
{ t.end() } -> std::same_as<typename T::iterator>;
};
// 使用概念约束模板
template<Numeric T>
T add(T a, T b) {
return a + b;
}
// 更复杂的概念
template<typename T>
concept Printable = requires(T t, std::ostream& os) {
{ os << t } -> std::same_as<std::ostream&>;
};
template<typename T>
concept Comparable = requires(T a, T b) {
{ a < b } -> std::convertible_to<bool>;
{ a > b } -> std::convertible_to<bool>;
{ a == b } -> std::convertible_to<bool>;
{ a != b } -> std::convertible_to<bool>;
};
// 组合概念
template<typename T>
concept SortableContainer = Container<T> &&
requires(T t) {
typename T::value_type;
requires Comparable<typename T::value_type>;
};
// 概念重载
template<std::integral T>
void process(T value) {
std::cout << "处理整数: " << value << std::endl;
}
template<std::floating_point T>
void process(T value) {
std::cout << "处理浮点数: " << value << std::endl;
}
template<Printable T>
requires (!Numeric<T>)
void process(T value) {
std::cout << "处理可打印对象: " << value << std::endl;
}
// 概念与auto
void auto_with_concepts() {
std::integral auto x = 42;
std::floating_point auto y = 3.14;
Container auto vec = std::vector<int>{1, 2, 3};
}
// 自定义概念示例
template<typename T>
concept Clock = requires(T c) {
typename T::rep;
typename T::period;
typename T::duration;
typename T::time_point;
{ T::now() } -> std::same_as<typename T::time_point>;
};
template<Clock C>
auto measure_time(auto func) {
auto start = C::now();
func();
auto end = C::now();
return end - start;
}
int main() {
// 使用概念约束的函数
std::cout << add(5, 3) << std::endl;
std::cout << add(5.5, 3.3) << std::endl;
// add("Hello", "World"); // 编译错误
// 概念重载
process(42);
process(3.14);
process(std::string("Hello"));
// 测试容器概念
static_assert(Container<std::vector<int>>);
static_assert(Container<std::list<double>>);
// static_assert(Container<int>); // 失败
// 使用Clock概念
auto duration = measure_time<std::chrono::steady_clock>([]() {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
});
std::cout << "执行时间: "
<< std::chrono::duration_cast<std::chrono::milliseconds>(duration).count()
<< "ms" << std::endl;
return 0;
}
10.3 协程 (C++20)
#include <iostream>
#include <coroutine>
#include <thread>
#include <chrono>
#include <vector>
#include <optional>
// 简单协程返回类型
template<typename T>
struct Generator {
struct promise_type {
T current_value;
Generator get_return_object() {
return Generator{std::coroutine_handle<promise_type>::from_promise(*this)};
}
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception() { std::terminate(); }
std::suspend_always yield_value(T value) {
current_value = value;
return {};
}
void return_void() {}
};
std::coroutine_handle<promise_type> h_;
explicit Generator(std::coroutine_handle<promise_type> h) : h_(h) {}
~Generator() { if (h_) h_.destroy(); }
// 移动构造
Generator(Generator&& other) noexcept : h_(std::exchange(other.h_, {})) {}
Generator& operator=(Generator&& other) noexcept {
if (this != &other) {
if (h_) h_.destroy();
h_ = std::exchange(other.h_, {});
}
return *this;
}
// 禁用拷贝
Generator(const Generator&) = delete;
Generator& operator=(const Generator&) = delete;
// 迭代器接口
struct iterator {
std::coroutine_handle<promise_type> h_;
iterator& operator++() {
h_.resume();
return *this;
}
T operator*() const {
return h_.promise().current_value;
}
bool operator==(std::default_sentinel_t) const {
return h_.done();
}
};
iterator begin() {
h_.resume();
return iterator{h_};
}
std::default_sentinel_t end() { return {}; }
};
// 生成器协程
Generator<int> fibonacci(int n) {
int a = 0, b = 1;
for (int i = 0; i < n; ++i) {
co_yield a;
auto temp = a;
a = b;
b = temp + b;
}
}
// 异步任务协程
struct Task {
struct promise_type {
Task get_return_object() {
return Task{std::coroutine_handle<promise_type>::from_promise(*this)};
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() noexcept { return {}; }
void unhandled_exception() { std::terminate(); }
void return_void() {}
};
std::coroutine_handle<promise_type> h_;
explicit Task(std::coroutine_handle<promise_type> h) : h_(h) {}
~Task() { if (h_) h_.destroy(); }
};
// 自定义awaiter
struct AsyncTimer {
std::chrono::milliseconds duration;
bool await_ready() const noexcept { return false; }
void await_suspend(std::coroutine_handle<> h) const {
std::thread([h, this]() {
std::this_thread::sleep_for(duration);
h.resume();
}).detach();
}
void await_resume() const noexcept {}
};
Task async_task() {
std::cout << "任务开始" << std::endl;
co_await AsyncTimer{std::chrono::milliseconds(1000)};
std::cout << "1秒后..." << std::endl;
co_await AsyncTimer{std::chrono::milliseconds(500)};
std::cout << "又过了0.5秒..." << std::endl;
std::cout << "任务完成" << std::endl;
}
// 协程与异常
struct Result {
struct promise_type {
std::optional<int> value;
std::exception_ptr exception;
Result get_return_object() {
return Result{std::coroutine_handle<promise_type>::from_promise(*this)};
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception() {
exception = std::current_exception();
}
void return_value(int v) {
value = v;
}
};
std::coroutine_handle<promise_type> h_;
int get() {
if (h_.promise().exception) {
std::rethrow_exception(h_.promise().exception);
}
return h_.promise().value.value();
}
};
Result compute_async(int x) {
if (x < 0) {
throw std::invalid_argument("负数输入");
}
co_return x * x;
}
int main() {
// 使用生成器
std::cout << "斐波那契数列: ";
for (int value : fibonacci(10)) {
std::cout << value << " ";
}
std::cout << std::endl;
// 异步任务
auto task = async_task();
// 等待任务完成
std::this_thread::sleep_for(std::chrono::seconds(2));
// 带异常的协程
try {
auto result = compute_async(5);
std::cout << "计算结果: " << result.get() << std::endl;
auto error_result = compute_async(-1);
std::cout << error_result.get() << std::endl;
} catch (const std::exception& e) {
std::cout << "捕获异常: " << e.what() << std::endl;
}
return 0;
}
10.4 范围 (C++20)
#include <iostream>
#include <vector>
#include <ranges>
#include <algorithm>
#include <numeric>
#include <string>
namespace ranges = std::ranges;
namespace views = std::views;
// 自定义范围适配器
template<typename Pred>
class filter_view : public ranges::view_interface<filter_view<Pred>> {
private:
std::vector<int>* data_;
Pred pred_;
public:
filter_view(std::vector<int>& data, Pred pred)
: data_(&data), pred_(pred) {}
auto begin() {
return ranges::find_if(*data_, pred_);
}
auto end() {
return data_->end();
}
};
// 投影和转换
struct Person {
std::string name;
int age;
double salary;
};
void demonstrate_ranges() {
// 基本范围操作
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// 过滤和转换
auto result = vec | views::filter([](int n) { return n % 2 == 0; })
| views::transform([](int n) { return n * n; });
std::cout << "偶数的平方: ";
for (int n : result) {
std::cout << n << " ";
}
std::cout << std::endl;
// 范围算法
ranges::sort(vec, std::greater{});
std::cout << "降序排序: ";
ranges::copy(vec, std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
// 组合视图
auto complex_view = vec | views::reverse
| views::take(5)
| views::transform([](int n) { return n * 2; });
std::cout << "复杂视图: ";
for (int n : complex_view) {
std::cout << n << " ";
}
std::cout << std::endl;
// 分割和连接
std::string text = "Hello,World,from,C++20,Ranges";
auto words = text | views::split(',')
| views::transform([](auto&& word) {
return std::string(word.begin(), word.end());
});
std::cout << "分割的单词: ";
for (const auto& word : words) {
std::cout << word << " ";
}
std::cout << std::endl;
// 投影
std::vector<Person> people = {
{"Alice", 25, 50000},
{"Bob", 30, 60000},
{"Charlie", 35, 70000},
{"David", 28, 55000}
};
ranges::sort(people, {}, &Person::age);
std::cout << "按年龄排序: ";
for (const auto& p : people) {
std::cout << p.name << "(" << p.age << ") ";
}
std::cout << std::endl;
// 范围生成
auto squares = views::iota(1, 11)
| views::transform([](int n) { return n * n; });
std::cout << "1-10的平方: ";
for (int n : squares) {
std::cout << n << " ";
}
std::cout << std::endl;
// 惰性求值
auto infinite = views::iota(1)
| views::filter([](int n) { return n % 7 == 0; })
| views::take(5);
std::cout << "前5个7的倍数: ";
for (int n : infinite) {
std::cout << n << " ";
}
std::cout << std::endl;
}
// 自定义范围概念
template<typename R>
concept IntRange = ranges::range<R> &&
std::same_as<ranges::range_value_t<R>, int>;
template<IntRange R>
int sum_range(R&& r) {
return std::accumulate(ranges::begin(r), ranges::end(r), 0);
}
int main() {
demonstrate_ranges();
// 使用自定义概念
std::vector<int> nums = {1, 2, 3, 4, 5};
std::cout << "范围和: " << sum_range(nums) << std::endl;
// 范围到容器
auto even_squares = views::iota(1, 11)
| views::filter([](int n) { return n % 2 == 0; })
| views::transform([](int n) { return n * n; });
std::vector<int> result(ranges::begin(even_squares),
ranges::end(even_squares));
std::cout << "偶数平方向量: ";
for (int n : result) {
std::cout << n << " ";
}
std::cout << std::endl;
return 0;
}
总结
本文档详细介绍了C++的高级技术特性,包括:
- 模板:函数模板、类模板、模板元编程
- 右值和移动语义:提高性能,避免不必要的拷贝
- 定位new:精确控制对象的内存位置
- 强类型:通过类型系统增强代码安全性
- 智能指针:自动内存管理,避免内存泄漏
- 容器和算法:STL的强大功能
- Lambda表达式:函数式编程支持
- constexpr:编译时计算
- 多线程和并发:现代并发编程
- C++20新特性:模块、概念、协程、范围
这些特性使C++成为一门强大而灵活的编程语言,适用于系统编程、游戏开发、高性能计算等多个领域。掌握这些高级特性将帮助您编写更高效、更安全、更易维护的C++代码。
编译和运行
在Visual Studio Code中编译这些示例,确保使用支持C++20的编译器:
# GCC 11+
g++ -std=c++20 -fcoroutines -pthread main.cpp -o main
# Clang 12+
clang++ -std=c++20 -stdlib=libc++ -pthread main.cpp -o main
# MSVC (Windows)
cl /std:c++20 /EHsc main.cpp
建议为不同的C++标准创建不同的编译任务,以便测试不同版本的特性。
文档特点:
完整覆盖所有主题:
模板(函数模板、类模板、模板元编程)
右值和移动语义
定位 new
强类型
智能指针(unique_ptr、shared_ptr、weak_ptr)
容器和算法
Lambda表达式
常量表达式(constexpr)
多线程和并发
C++20新特性(模块、概念、协程、范围)
丰富的代码示例:
每个主题都有多个实际可运行的代码示例
代码包含详细的中文注释
从基础用法到高级技巧的递进式示例
VS Code开发支持:
提供了tasks.json配置示例
包含不同编译器的编译命令
支持C++20标准
实用性强:
涵盖实际开发中的常见场景
提供最佳实践建议
包含性能优化技巧