Content
20 Lessons • 0 Quizzes • 0 Challenges
简介
- 1
语言特性
- 2
使用映射
- 3
调试打印
- 4
开始吧!
已移除或修复的语言特性
- 1
简介
- 2
移除元素
- 3
去除 'register' 关键字
- 4
删除已弃用的运算符 ++ (bool)
- 5
删除已弃用的异常说明
- 6
删除三字符序列
- 7
修复
- 8
static_assert 无消息
- 9
编译器支持
已移除和弃用的库功能
- 1
简介
- 2
移除 auto_ptr
- 3
移除了 std::random_shuffle
- 4
移除旧的函数式代码
- 5
`std::iterator` 已被弃用
- 6
其他较小的移除或已弃用项目
- 7
编译器支持
语言说明
- 1
简介
- 2
表达式求值顺序
- 3
C++17 中的求值顺序
- 4
保证的拷贝消除
- 5
命名返回值优化
- 6
不可移动/不可复制类型
- 7
更新的值类别
- 8
gl/prvalue 的简化
- 9
超对齐数据的动态内存分配
- 10
类型系统中的异常规范
- 11
测验
- 12
编译器支持
模板
- 1
简介
- 2
类模板的模板参数推导
- 3
推导指南
- 4
折叠表达式
- 5
示例 - 折叠表达式
- 6
if constexpr
- 7
模板代码简化
- 8
示例 - 模板代码简化
- 9
使用 auto 声明非类型模板参数
- 10
C++17 中的其他修改
- 11
测验
- 12
编译器支持
通用语言特性
- 1
简介
- 2
结构化绑定声明
- 3
语法
- 4
修饰符与限制
- 5
绑定
- 6
为自定义类提供结构化绑定接口
- 7
if 和 switch 语句的初始化语句
- 8
在搜索语句中使用 if
- 9
内联变量
- 10
它如何简化代码
- 11
constexpr Lambda 函数
- 12
在 Lambda 表达式中捕获 *this
- 13
嵌套命名空间
- 14
__has_include 预处理器表达式
- 15
测验
- 16
编译器支持
标准属性
- 1
简介
- 2
为什么我们需要属性?
- 3
在 C++11 之前
- 4
C++11/C++14 中的属性
- 5
C++17 新增特性
- 6
第三个标准属性
- 7
命名空间/枚举器属性
- 8
关于属性的更多内容
- 9
总结
- 10
测验
- 11
编译器支持
std::optional
- 1
简介
- 2
标准库的变更
- 3
std::optional 的一个基本示例
- 4
std::optional 的创建
- 5
就地构造
- 6
默认构造
- 7
带多个参数的构造函数
- 8
返回 std::optional
- 9
返回时注意大括号的使用
- 10
访问存储的值
- 11
std::optional 上的操作
- 12
std::optional 的使用示例
- 13
性能与内存考虑
- 14
特殊情况:optional<bool> 和 optional<T*>
- 15
摘要
- 16
测验
- 17
编译器支持
std::variant
- 1
简介
- 2
基础内容
- 3
std::variant 示例
- 4
何时使用 std::variant
- 5
std::variant 创建
- 6
原地构造
- 7
歧义与复杂类型
- 8
更改值
- 9
对象生命周期
- 10
访问存储的值
- 11
std::variant 的访问者
- 12
重载
- 13
访问多个变体
- 14
异常安全保证
- 15
性能与内存考虑
- 16
std::variant 的示例 std::variant 是 C++17 引入的一种类型安全的联合体(union),可以存储多种不同类型的值,但同一时间只能存储其中一种。它通过 std::variant<T1, T2, ..., TN> 定义,其中 T1 到 TN 是可选的类型。 以下是几个使用 std::variant 的示例: 1. 基本用法:存储不同类型的数据 ```cpp #include <iostream> #include <variant> #include <string> int main() { std::variant<int, double, std::string> v; v = 42; // 存储 int std::cout << std::get<int>(v) << std::endl; v = 3.14; // 存储 double std::cout << std::get<double>(v) << std::endl; v = "Hello"; // 存储 std::string std::cout << std::get<std::string>(v) << std::endl; return 0; } ``` 2. 使用 std::visit 进行访问和操作 ```cpp #include <iostream> #include <variant> #include <string> struct Printer { void operator()(int i) const { std::cout << "Integer: " << i << std::endl; } void operator()(double d) const { std::cout << "Double: " << d << std::endl; } void operator()(const std::string& s) const { std::cout << "String: " << s << std::endl; } }; int main() { std::variant<int, double, std::string> v = "World"; std::visit(Printer{}, v); // 调用对应的重载函数 return 0; } ``` 3. 检查当前存储的类型 ```cpp #include <iostream> #include <variant> #include <typeinfo> int main() { std::variant<int, double, std::string> v = 100; if (std::holds_alternative<int>(v)) { std::cout << "Current type is int" << std::endl; } else if (std::holds_alternative<double>(v)) { std::cout << "Current type is double" << std::endl; } else if (std::holds_alternative<std::string>(v)) { std::cout << "Current type is string" << std::endl; } return 0; } ``` 4. 使用 std::variant 作为函数返回值 ```cpp #include <iostream> #include <variant> #include <string> std::variant<int, std::string> parseNumber(const std::string& str) { try { size_t pos; int value = std::stoi(str, &pos); if (pos == str.length()) { return value; } } catch (...) { // 解析失败,返回字符串 return "Invalid number"; } return "Invalid number"; } int main() { auto result = parseNumber("123"); if (std::holds_alternative<int>(result)) { std::cout << "Parsed integer: " << std::get<int>(result) << std::endl; } else { std::cout << "Error: " << std::get<std::string>(result) << std::endl; } return 0; } ``` 5. 多层嵌套 variant 示例 ```cpp #include <iostream> #include <variant> #include <vector> using Data = std::variant<int, double, std::string, std::vector<std::variant<int, double>>>; int main() { Data data = std::vector<std::variant<int, double>>{1, 2.5, 3}; std::visit([](auto&& arg) { using T = std::decay_t<decltype(arg)>; if constexpr (std::is_same_v<T, std::vector<std::variant<int, double>>>) { for (const auto& item : arg) { std::visit([](auto&& val) { std::cout << val << " "; }, item); } std::cout << std::endl; } }, data); return 0; } ``` 注意事项: - 使用 std::get<T>(v) 时,必须确保当前存储的类型与 T 匹配,否则程序行为未定义。 - 推荐使用 std::visit 来安全地处理所有可能的类型。 - 可以使用 std::holds_alternative<T>(v) 检查当前存储的类型是否为 T。 - std::variant 不支持非平凡构造函数或析构函数的类型(如包含动态内存分配的类),除非这些类型是可移动且无异常抛出的。 std::variant 提供了一种类型安全、高效的方式来处理多种可能的数据类型,是替代传统 union 的现代方式。
- 17
解析命令行
- 18
解析与状态机
- 19
多态性
- 20
总结
- 21
测验
- 22
编译器支持
std::any
- 1
简介
- 2
基础内容
- 3
对象创建
- 4
访问存储的值
- 5
性能与内存考虑
- 6
从 boost::any 迁移
- 7
总结
- 8
编译器支持
std::string_view
- 1
简介
- 2
基础内容
- 3
何时使用
- 4
std::basic_string_view 类型
- 5
std::string_view 的创建
- 6
其他操作
- 7
使用 string_view 的风险
- 8
初始示例的问题
- 9
引用生命周期延长
- 10
在选择使用 string 还是 string_view 时的考虑
- 11
从 string_view 初始化字符串成员
- 12
处理非空结尾字符串
- 13
使用 printf() 打印输出
- 14
转换函数,如 atoi()/atof()
- 15
通用解法
- 16
性能与内存考虑
- 17
常量表达式中的字符串
- 18
从 boost::string_ref 和 boost::string_view 迁移
- 19
示例:使用不同的字符串 API
- 20
示例:字符串分割
- 21
总结
- 22
测验
- 23
编译器支持
搜索者与字符串匹配
- 1
简介
- 2
字符串匹配算法概述
- 3
C++17 中新增的算法
- 4
使用搜索器
- 5
示例 - 使用搜索器
- 6
DNA 匹配
- 7
总结
- 8
编译器支持
字符串转换
- 1
简介
- 2
基本的字符串转换
- 3
from_chars
- 4
示例
- 5
to_chars
- 6
基准测试
- 7
总结
- 8
测验
- 9
编译器支持
文件系统
- 1
简介
- 2
概览
- 3
演示:递归列出目录树
- 4
路径对象
- 5
路径组合
- 6
目录条目与目录遍历
- 7
支持函数
- 8
文件权限
- 9
错误处理与文件竞争
- 10
std::filesystem 的使用示例
- 11
总结
- 12
编译器支持
并行 STL 算法
- 1
简介
- 2
C++17 的并行性
- 3
执行策略
- 4
并行/顺序策略使用
- 5
异常
- 6
算法更新
- 7
ForEach 和 Reduce 算法
- 8
更多算法
- 9
并行算法的性能
- 10
基准测试 I
- 11
基准测试 II
- 12
处理容器
- 13
并行算法中的错误方法
- 14
计数元素
- 15
摘要
- 16
测验
- 17
编译器支持
库中的其他更改
- 1
简介
- 2
std::byte
- 3
Maps 和 Sets 的优化改进
- 4
映射和无序映射的 emplace 增强功能
- 5
emplace 方法的返回类型
- 6
采样算法
- 7
新的数学函数
- 8
共享指针和数组
- 9
非成员函数 size()、data() 和 empty()
- 10
标准库的 constexpr 改进
- 11
std::scoped_lock
- 12
多态分配器
- 13
编译器支持
使用 std::optional 和 std::variant 进行重构
- 1
简介
- 2
用例
- 3
元组版本
- 4
一个独立的结构
- 5
使用 std::optional
- 6
使用 std::variant
- 7
总结
使用 [[nodiscard]] 强制执行代码契约
- 1
简介
- 2
它可以在哪些场景中使用?
- 3
到处都是?!
- 4
如何忽略 [[nodiscard]]
- 5
总结
使用 if constexpr 替代 enable_if - 支持可变参数的工厂模式
- 1
简介
- 2
使用 if constexpr
- 3
总结
如何并行化 CSV 读取
- 1
简介
- 2
应用需求
- 3
串行版本
- 4
核心部分
- 5
将行转换为记录
- 6
OrderRecord 类
- 7
计算
- 8
使用并行算法
- 9
数据大小和指令数量很重要
- 10
并行数据转换
- 11
并行计算
- 12
测试
- 13
总结与讨论
Certificate of Completion
Showcase your accomplishment by sharing your certificate of completion.
Course Author:Anonymous User