// cpp20_demo.cpp
// 编译: g++ -std=c++20 -pthread cpp20_demo.cpp -o cpp20_demo
// 运行: ./cpp20_demo
#include <iostream> // 输入输出
#include <format> // C++20 格式化库
#include <concepts> // C++20 概念
#include <ranges> // C++20 范围库
#include <span> // C++20 span
#include <vector> // 动态数组
#include <string> // 字符串
#include <array> // 固定数组
#include <algorithm> // 算法
#include <compare> // 三路比较
#include <coroutine> // 协程支持
#include <optional> // 可选值
#include <numbers> // 数学常量
// ============================================================
// 全局辅助
// ============================================================
template<typename T> // 定义概念
concept Addable = requires(T a, T b) { // 要求 a + b 合法
{ a + b } -> std::same_as<T>; // 且返回类型是 T
};
template<Addable T> // 用概念约束
T add(const T& a, const T& b) { // 通用加法
return a + b; // 返回结果
}
struct Point { // 三路比较
int x, y; // 坐标
auto operator<=>(const Point&) const = default; // 自动生成所有比较
};
struct WindowConfig { // 指定初始化器
int width = 800; // 默认宽
int height = 600; // 默认高
std::string title = "Untitled"; // 默认标题
};
consteval int compile_time_square(int x) { // 必须编译期求值
return x * x; // 返回平方
}
constinit int global_init = compile_time_square(5); // 编译期初始化
template<typename T> // 生成器模板
struct Generator { // 协程生成器
struct promise_type { // 协程承诺类型
T current_value; // 当前值
auto get_return_object() { // 创建返回对象
return Generator{ std::coroutine_handle<promise_type>::from_promise(*this) };
}
auto initial_suspend() { return std::suspend_never{}; } // 立即开始
auto final_suspend() noexcept { return std::suspend_always{}; } // 结束保持挂起
void return_void() {} // 无返回值
void unhandled_exception() { std::terminate(); } // 异常终止
auto yield_value(T value) { // co_yield 处理
current_value = value; // 保存值
return std::suspend_always{}; // 暂停等待恢复
}
};
std::coroutine_handle<promise_type> handle; // 协程句柄
explicit Generator(std::coroutine_handle<promise_type> h) : handle(h) {} // 构造
Generator(const Generator&) = delete; // 禁止拷贝
Generator& operator=(const Generator&) = delete; // 禁止拷贝赋值
Generator(Generator&& o) noexcept : handle(o.handle) { o.handle = nullptr; } // 移动构造
Generator& operator=(Generator&& o) noexcept { // 移动赋值
if (this != &o) { // 防止自赋值
if (handle) handle.destroy(); // 销毁旧句柄
handle = o.handle; // 接管新句柄
o.handle = nullptr; // 置空源对象
}
return *this; // 返回自身
}
~Generator() { if (handle) handle.destroy(); } // 析构销毁
bool next() { // 恢复协程
if (!handle || handle.done()) return false; // 已结束
handle.resume(); // 恢复执行
return !handle.done(); // 是否还有值
}
T value() const { return handle.promise().current_value; } // 获取当前值
};
Generator<int> count_up_to(int max) { // 生成 1..max
for (int i = 1; i <= max; ++i) // 循环
co_yield i; // 产出并暂停
}
void print_span(std::span<const int> data, std::string_view label) { // span 打印
std::cout << label << ": "; // 提示
for (int x : data) std::cout << x << " "; // 遍历
std::cout << "\n"; // 换行
}
// ============================================================
// main
// ============================================================
int main() { // 程序入口
std::cout << "1. 概念:\n"; // 提示
std::cout << " add(3,4) = " << add(3, 4) << "\n"; // int
std::cout << " add(1.5,2.5) = " << add(1.5, 2.5) << "\n"; // double
static_assert(Addable<int>); // 编译期检查
std::cout << "2. 三路比较:\n"; // 提示
Point p1{1, 2}, p2{3, 4}; // 两个点
std::cout << " p1 < p2: " << (p1 < p2) << "\n"; // 自动生成
std::cout << "3. 指定初始化器:\n"; // 提示
WindowConfig cfg2{ .width = 1024, .height = 768 }; // 指定部分成员
std::cout << " " << cfg2.width << "x" << cfg2.height
<< " " << cfg2.title << "\n"; // 输出
std::cout << "4. consteval / constinit:\n"; // 提示
constexpr int sq = compile_time_square(6); // 编译期
std::cout << " sq = " << sq << ", global_init = " << global_init << "\n"; // 输出
std::cout << "5. std::format:\n"; // 提示
std::cout << " " << std::format("{} 的年龄是 {}\n", "Alice", 30); // 基本
std::cout << " " << std::format("{:.2f}\n", 95.5); // 精度
std::cout << " " << std::format("|{:<10}|{:>10}|{:^10}|\n", "left", "right", "center"); // 对齐
std::cout << "6. std::span:\n"; // 提示
int carr[] = {1, 2, 3, 4, 5}; // C 数组
std::vector<int> vec = {10, 20, 30}; // vector
std::array<int, 4> arr = {100, 200, 300, 400}; // array
print_span(carr, " C array"); // 打印
print_span(vec, " vector"); // 打印
print_span(arr, " array"); // 打印
std::cout << "7. Ranges / Views:\n"; // 提示
std::vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 数据源
std::cout << " views: "; // 提示
auto result = nums // 从 nums 开始
| std::views::filter([](int x) { return x % 2 == 0; }) // 筛选偶数
| std::views::transform([](int x) { return x * x; }) // 平方
| std::views::take(3); // 取前 3
for (int x : result) std::cout << x << " "; // 输出
std::cout << "\n"; // 换行
std::cout << " reverse: "; // 提示
for (int x : nums | std::views::reverse | std::views::take(3)) // 反转取前 3
std::cout << x << " "; // 输出
std::cout << "\n"; // 换行
std::cout << "8. 协程:\n"; // 提示
auto gen = count_up_to(5); // 创建生成器
std::cout << " coroutine: "; // 提示
while (gen.next()) { // 逐个恢复
std::cout << gen.value() << " "; // 输出当前值
}
std::cout << "\n"; // 换行
std::cout << "9. 数学常量:\n"; // 提示
std::cout << " " << std::format("pi = {:.10f}\n", std::numbers::pi); // π
std::cout << " " << std::format("e = {:.10f}\n", std::numbers::e); // e
std::cout << "\n全部 C++20 示例运行完毕。\n"; // 结束提示
return 0; // 正常返回
}