查看: 111|回复: 1

《C++20高级编程上册》C++和标准库速成(一)

[复制链接]

1

主题

7

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2022-12-28 13:47:00 | 显示全部楼层 |阅读模式
注:这里摘录的知识点不全面,只是本人认为于己应该记录下来。如果想全面了解新版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("Max double value {}\n", std::numeric_limits<double>::max());
    std::cout << std::format("Min double value {}\n", std::numeric_limits<double>::min());
    std::cout << std::format("Lowest double value {}\n", 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 << "i大于0" << 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("Some explanation")]]
[[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("reason to not use")]]
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, "code" };
    auto [a, b] {tmpPair}; // a=100 b="code"

    return 1;
}
回复

使用道具 举报

4

主题

12

帖子

25

积分

新手上路

Rank: 1

积分
25
发表于 2025-4-6 03:04:19 | 显示全部楼层
是爷们的娘们的都帮顶!大力支持
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表