|
注:这里摘录的知识点不全面,只是本人认为于己应该记录下来。如果想全面了解新版C++知识点,建议直接上书。
如特性在Visual Studio未实现,可到这里验证:
(C++20)模块导入
C++ 20中最重要的特性之一就是对模块的支持,用来替代之前所谓的头文件机制。
导入自定义模块时,不使用尖括号。
import <iostream>
// 模块接口文件
export module ariline_ticket; // 导出模块
export class AirlineTicket { // 模块中被导出的类型
}
// 模块源文件
module airline_ticket; // 表明是模块源文件
输入输出流
请记住 endl 会在流中插入新的一行,并且把当前缓冲区的所有内容刷出滑槽。不建议过度地使用 endl,例如在循环中使用,因为这会影响程序的性能。另一方面,在流中插入 \n 也会插入新的一行,但不会自动刷新缓冲区。
数值极限
不建议使用如 INT_MAX 的宏定义,而是使用 <limits> 中的类模板 std::numeric_limits。
#include <iostream>
#include <limits> // numeric_limits
#include <format> // format
int main()
{
std::cout << std::format(&#34;Max double value {}\n&#34;, std::numeric_limits<double>::max());
std::cout << std::format(&#34;Min double value {}\n&#34;, std::numeric_limits<double>::min());
std::cout << std::format(&#34;Lowest double value {}\n&#34;, std::numeric_limits<double>::lowest());
return 1;
}
// Max double value 1.7976931348623157e+308
// Min double value 2.2250738585072014e-308 // 最小正数
// Lowest double value -1.7976931348623157e+308 // 最小负数
注意min() 和 lowest() 之间的区别。
对于一个整数,最小值等于最低值。
然而对于浮点类型来说,最小值表示该类型能表示的最小正数,最低值表示该类型能表示的最小负数,即-max()。
零初始化
可以用一个{0}的统一初始化器将变量初始化为0,0在这里是可选的。
一对空的花括号组成的统一初始化器,{},称为零初始化器。
零初始化会将原始的整数类型(char,int)初始化为0。
指针类型初始化为nullptr。
对象用默认构造函数初始化。
模块接口文件
模块接口文件通常以 .cppm 作为后缀。
if语句的初始化器
if初始化器格式:
if (<initializer>; <conditional_expression>) {
}
<initializer> 中引入的变量只在if语句中可用,if语句以外不可用。
#include <iostream>
#include <array>
int main()
{
// if 初始化器
if (int i = 100; i > 0) {
std::cout << &#34;i大于0&#34; << std::endl;
}
//int j = i; // 未定义标识符 i
// for 初始化器以及基于范围的for循环
for (std::array tmpArr{ 1,3,1,4 }; auto item: tmpArr) {
std::cout << item << std::endl;
}
}
for 循环,switch 语句也有类似的初始化器。
fallthrough
一旦找到与switch条件匹配的case表达式,就执行其后的所有语句,直至遇到break为止。即使遇到另一个case表达式,执行也会继续,这称为fallthrough。
如果漏写break,一些编译器还会给出警告,而使用[[fallthrough]]则是告诉编译器,我是故意这样的。
#include <iostream>
int main()
{
int i = 2;
switch (i) {
case 1:
std::cout << 1 << std::endl;
break;
case 2:
std::cout << 2 << std::endl;
[[fallthrough]]; // 故意为之,也算是提醒维护者,这里不是疏忽
case 100:
std::cout << 100 << std::endl;
break;
}
return 1;
}
(C++20)三向比较符(太空飞船操作符)
如果操作数是整数类型,则结果是所谓的强排序(string_ordering)。
如果操作数是浮点类型,结果则是一个偏序(partial_ordering)。
如果操作数是自定义类型,则是弱排序(weak_ordering).

属性 [[]]
[[nodiscard(&#34;Some explanation&#34;)]]
[[nodiscard]] int getTime() {
return 12;
}
用于一个函数的返回值,使编译器在该函数被调用却没有对返回值进行任何处理时发出警告。
[[maybe_unused]]
#include <iostream>
int getTime(int param1, [[maybe_unused]]int param2) {
return 1 + param1;
}
int main()
{
auto time = getTime(1, 2);
return 1;
}
禁止编译器在未使用某些内容时发出警告。
[[no_return]]
[[noreturn]] void god() {
std::exit(1);
}
int main()
{
god();
return 1;
}
表示不会将控制权返回给调用点。
[[deprecated]]
[[deprecated(&#34;reason to not use&#34;)]]
void god() {
// do nothing
}
int main()
{
god();
return 1;
}
用于将某些内容标记为已弃用。
std::array
对C风格的数组进行了简单的包装。
需要记住:必须在尖括号中指定两个参数。第一个参数表示数组中元素的类型,第二个参数表示数组的大小。
结构化绑定
注意:必须为结构化绑定使用 auto 关键字。
使用结构化绑定声明的变量数量必须与右侧表达式中的值数量匹配。
int main()
{
std::array<int, 3> tmpArr{ 1, 2, 3 };
auto [x, y, z] = tmpArr;
std::cout << x << y << z << std::endl; // 123
std::pair<int, std::string> tmpPair{ 100, &#34;code&#34; };
auto [a, b] {tmpPair}; // a=100 b=&#34;code&#34;
return 1;
} |
|