C++高级技术详解

C++高级技术详解

目录

  1. 模板 (Templates)
  2. 右值和移动语义 (Rvalue and Move Semantics)
  3. 定位 new (Placement new)
  4. 强类型 (Strong Types)
  5. 智能指针 (Smart Pointers)
  6. 容器和算法 (Containers and Algorithms)
  7. Lambda表达式
  8. 常量表达式 (constexpr)
  9. 多线程和并发 (Multithreading and Concurrency)
  10. 现代C++特性:模块、概念、协程和范围

环境配置

在Visual Studio Code中开发C++需要:

  1. 安装C++扩展
  2. 配置编译器(GCC、Clang或MSVC)
  3. 创建tasks.jsonlaunch.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;           // 20std::cout << max(10.5, 20.3) << std::endl;       // 20.3std::cout << add(10, 20.5) << std::endl;         // 30.5print("Hello", "World", 123, 45.6);  // Hello World 123 45.6return 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;  // 20return 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;  // 120std::cout << is_odd(5) << std::endl;  // 1std::cout << process(10) << std::endl;    // 20std::cout << process(10.0) << std::endl;  // 5.0return 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);        // 左值引用: 10processValue(20);       // 右值引用: 20processValue(std::move(a));  // 右值引用: 10universalRef(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();  // 销毁观察者1std::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 10pq.pop();}std::cout << std::endl;// C++11 arraystd::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 lambdaauto 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;        // intstd::cout << genericAdd(3.5, 4.5) << std::endl;    // doublestd::cout << genericAdd(std::string("Hello"), std::string(" World")) << std::endl;  // stringreturn 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() {// 使用递归lambdastd::cout << "5! = " << factorial(factorial, 5) << std::endl;std::cout << "fib(10) = " << fib(10) << std::endl;// Lambda与STLstd::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;// 状态lambdaauto 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与asyncstd::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;// 并行算法与lambdastd::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;   // 10std::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() {// 比较模板元编程和constexprconstexpr 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;// 线程IDstd::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++17std::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和Futurestd::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 futurestd::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++的高级技术特性,包括:

  1. 模板:函数模板、类模板、模板元编程
  2. 右值和移动语义:提高性能,避免不必要的拷贝
  3. 定位new:精确控制对象的内存位置
  4. 强类型:通过类型系统增强代码安全性
  5. 智能指针:自动内存管理,避免内存泄漏
  6. 容器和算法:STL的强大功能
  7. Lambda表达式:函数式编程支持
  8. constexpr:编译时计算
  9. 多线程和并发:现代并发编程
  10. 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标准

实用性强:

涵盖实际开发中的常见场景
提供最佳实践建议
包含性能优化技巧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90014.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90014.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跨境卖家紧急自查,Endryko Karmadi四季版画版权维权

25年7月2日&#xff0c;Keith律所代理印尼艺术家Endryko Karmadi发起全新版权维权行动。案件基本情况&#xff1a;起诉时间&#xff1a;2025-7-2案件号&#xff1a;25-cv-07436品牌&#xff1a;Endryko Karmadi Work原告&#xff1a;Endryko Karmadi 原告律所&#xff1a;keith…

M3088NL是一款网络滤波器/变压器支持100M和1000M网络环境,适用于高速网络传输场景M3088

M3088NL是一款网络滤波器/变压器&#xff0c;主要特点如下&#xff1a;兼容性 支持100M和1000M网络环境&#xff0c;适用于高速网络传输场景。 ‌封装形式 采用SOP/SOIC封装&#xff0c;便于电路集成。 ‌应用场景 常用于网络电话、开关电源等需要稳定电流的设备&#xff0c;符…

PyQt动态布局管理器:QSplitter详细指南

PyQt动态布局管理器&#xff1a;QSplitter详细指南 QSplitter简介 在PyQt中&#xff0c;除了常见的QVBoxLayout、QHBoxLayout等静态布局管理器外&#xff0c;QSplitter提供了一种动态布局解决方案。QSplitter允许用户通过拖拽分隔条来实时调整控件大小&#xff0c;为应用程序提…

Java设计模式之行为型模式(备忘录模式)实现方式详解

最近看到一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站 一、基础实现结构 角色定义与代码骨架 备忘录模式包含三个核心角色&#xff0c;其协作关系如下&#xff1a; Originator&#xff08;发起人&…

k8s:离线部署tomcatV11.0.9,报Cannot find /opt/bitnami/tomcat/bin/setclasspath.sh

本文记录了在离线环境下部署Tomcat容器时遇到的权限问题及解决方案。在Docker环境中运行Tomcat时出现&quot;找不到setclasspath.sh&quot;错误&#xff0c;通过添加--security-opt seccompunconfined参数解决。在Kubernetes环境中部署时出现相同问题&#xff0c;通过设置…

Linux操作系统之线程(五):线程封装

目录 前言 一、线程ID及进程地址空间布局 二、线程栈与线程局部存储 三、线程封装 总结&#xff1a; 前言 我们在上篇文章着重给大家说了一下线程的控制的有关知识。 但是如果我们要使用线程&#xff0c;就得那这pthread_create接口直接用吗&#xff1f;这样岂不是太过麻…

【物理与机器学习】从非平衡热力学到扩散模型

[toc] 0.引子:从非平衡热力学开始 1.架构简介 2.反向过程的具体推导与 DDPM 改进摘要&#xff1a;扩散模型将非平衡热力学的“噪声注入—去噪逆转”理念注入生成建模中。DDPM&#xff08;Denoising Diffusion Probabilistic Models&#xff09;在 SD2015 的基础上&#xff0c;通…

Git常用命令详解:从入门到精通

前言 Git作为当今最流行的分布式版本控制系统&#xff0c;已经成为开发者必备的技能之一。无论你是独立开发者还是团队协作&#xff0c;掌握Git的基本操作都能极大提高工作效率。本文将详细介绍Git的常用命令&#xff0c;帮助你快速上手并精通Git的基本使用。 一、Git基础概念…

Vue-22-通过flask接口提供的数据使用plotly.js绘图(一)

文章目录 1 任务背景 2 Flask提供接口(server.py) 2.1 原始代码 2.2 跨域问题 3 Vue3获取数据并渲染Plotly图表 3.1 新建工程 3.2 程序 3.2.1 index.html(入口) 3.2.2 cpmponents/Plot.vue(子组件) 3.2.3 App.vue(父组件) 3.2.4 main.ts 3.3 展示 4 选择图表类型绘图 4.1 App.v…

【mysql】换主键

需求&#xff1a;曲库表的主键错了&#xff0c;原先设置的是(sang_id),应该设置为&#xff08;sang_name,singer&#xff09;联合主键。-- &#xff08;0&#xff09;先备份数据&#xff0c;我这里没备份 -- &#xff08;1&#xff09;进行主键的切换之前&#xff0c;要进行一些…

Redis原理之缓存

上篇文章&#xff1a; Redis原理之集群https://blog.csdn.net/sniper_fandc/article/details/149141342?fromshareblogdetail&sharetypeblogdetail&sharerId149141342&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link 目录 1 Redis作为MySQL…

关于集合的底层数据结构

单列集合Collection分为list集合和set集合list集合分为ArrayList和LinkedListArrayList--底层数据结构是数组1.通过索引查询快2.增删要重构索引,增删慢 LinkedList--底层数据结构是链表1.无索引查询慢2.通过改变前节点的尾指针和后节点的前指针指向可快速增删,增删快set集合(…

批量插入技巧:减少事务提交次数的性能提升

一、事务提交成本分析每次事务提交触发‌磁盘I/O同步‌&#xff08;WAL机制&#xff09;、‌日志写入‌和‌锁资源释放‌操作&#xff0c;高频独立提交会产生指数级开销‌。实验表明&#xff1a;MySQL提交1万次单条插入比单次批量插入‌慢20倍以上‌‌。高频提交还加剧锁竞争与…

importlib.import_module() 的用法与实战案例

&#x1f31f; 一、什么是 importlib&#xff1f; importlib 是 Python 的一个内置标准库&#xff0c;用于在程序运行时 动态导入模块。 &#x1f524; 对比&#xff1a;普通 import vs importlib方式示例特点静态导入import os编写代码时就确定要导入的模块动态导入importlib.…

Oracle 12c 创建数据库初级教程

1. 连接到Oracle sqlplus / as sysdba Oracle数据库名称默认为ORCL或sqlplus /ORCL as sysdba Oracle数据库名称默认为ORCL2. 创建表空间&#xff08;数据库&#xff09; create user YOUR_USERNAME identified by "YOUR_PASSWORD"; YOUR_USERNAME为数据库名称和登…

zabbix服务器告警处理

zabbix服务器告警&#xff0c;信息为&#xff1a;Utilization of poller processes over 75%处理办法为修改zabbix_server.conf配置文件&#xff0c;一般情况下为/etc/zabbix目录下。根据自己轮询器的类型修改对应的轮询器的数量&#xff1b;我这里把StartPollers&#xff0c;S…

随笔20250721 PostgreSQL实体类生成器

我来帮你创建一个C#程序&#xff0c;从PostgreSQL数据库读取表结构并生成对应的实体类文件。我已经创建了一个完整的PostgreSQL实体类生成器。这个程序包含以下主要功能&#xff1a;主要特性数据库连接: 使用Npgsql连接PostgreSQL数据库表结构读取: 自动读取所有表的结构信息类…

B树、B-树与B+树

B树、B-tree与B树 在计算机科学&#xff0c;尤其是数据库和文件系统的领域中&#xff0c;B树、B-tree和B树是理解数据如何被高效存储和检索的关键。它们之间关系紧密&#xff0c;但功能和应用上又存在着决定性的差异。 一、 核心概念澄清&#xff1a;B树就是B-tree 首先需要明确…

视频格式转换工厂v3.2.5,集音视频、图片处理78MB

今天&#xff0c;我们要介绍的是一款功能强大的视频处理软件——视频格式转换工厂。这款软件已经完美破解&#xff0c;无需登录即可享受全部高级功能。它不仅支持视频格式转换&#xff0c;还涵盖了音频、图片处理等多种功能&#xff0c;是一款真正的多媒体处理工具。 视频格式转…

VUE 中父级组件使用JSON.stringify 序列化子组件传递循环引用错误

背景 VUE 中父级组件使用JSON.stringify 序列化子组件传递的数据会报错 runtime-core.esm-bundler.js:268 Uncaught TypeError: Converting circular structure to JSON –> starting at object with constructor ‘Object’ — property ‘config’ closes the circle 原因…