一、新关键字

1、auto 和 decltype 类型推断

string name = "asdf";
auto iter = name.begin();
decltype(name) username;

返回值类型后置:

template<typename T, typename U>
auto product(const T& t, const U& u) -> decltype (t* u)
{return t * u;
}

2、nullptr   空指针,替代原来的0和NULL

char *name = nullptr;

if(name==nullptr) .......

3、列表初始化

unordered_map<string, double>  grades =
{
{"lily",98.5},{"lucy",90.5},{"lilei",79.8}
};

4、非成员的迭代器

const char* names[]{ "Huey", "Dewey", "Louie" };
auto firstGT4 = find_if(begin(names), end(names),
[](const auto & s) {return strlen(s) > 4; });
cout << *firstGT4 << endl;const char names[]{ 'a','b','c','d' };
auto firstc = find_if(std::begin(names), std::end(names),
[](const char a) { return a == 'c'; });

std::cbegin() / std::cend();
std::rbegin / std::rend();
std::crbegin / std::crend();

5、基于范围的for循环

list<int> li ={ 10, 3, 8, 12, -54, 11, 458 };
for (auto& elt : li)  elt += 10000;
for (const auto& elt : li)          cout << elt << " ";  

6、编译期的断言

static_assert(condition, “message”);

 static_assert(sizeof(long long) >= 8,"This app requires long long to be at least 64 bits.");

7、noexcept,constexpr  常量表达式

8、enum classes

enum color {red,yellow,green = 20,blue
};

9、类的定义

=default, =delete

override / final   override函数必须在基类有定义,且为虚函数, final 修饰的成员函数不允许子类重载该虚函数,final 修饰的类不允许被继承。

定义类时初始化成员变量:

class Derived : public Base
{
public: void f(int) override;    void h(int) {};
public:int age = 20;static const int book = 500;static int price = 30; //非常量不能在定义时初始化
};

二、Lambdas表达式

局部变量捕获方式:

引用捕获: [&variable1, &variable2]

值捕获和引用捕获:[variable1, &variable2]

[=] (or) [&]

[=, &variable1]

三、类的构造和赋值函数

增加了移动构造函数和移动赋值函数,现有6大构造函数

class Big {
public:Big(); // 1. default ctor~Big(); // 2. destructorBig(int x); // (non-canonical)Big(const Big&); // 3. copy ctorBig& operator=(const Big&); // 4. copy assign.Big(Big&&); // 5. move ctorBig& operator=(Big&&); // 6. move assign.
private:    double x; // other data…
};

四、字符编码

1、不同编码的字符类型

Linux上的wchar_t是32位的,windows为16位(某些unicode字符无法表示)。三种可选的unicode编码:
utf32:一个码位固定4字节,一个码位表示一个字符编码。
utf16:兼容之前的16位编码,一个码位2字节,但1或2个码位表示一个字符编码(所以有可能会有问题)。
utf8:兼容ASCII编码,一个码位1字节,但1到6个码位表示一个字符编码。(现行标准其实要求最多4个码位,但出于保障兼容性的原因,5、6个码位的情况是可能出现的,即使这算无效编码。)

// ascii(本地)编码 对应 std::string
string str = "中国";// 宽字符编码 对应 std::wstring
wstring wstr = L"中国";// 16位固定宽度unicode编码, 小写字母u前缀 对应 std::u16string
u16string     c16str = u"中国";// 32位固定宽度unicode编码, 大写字母U前缀 对应 std::u32string
u32string c32str = U"中国";// 宽度不固定多字节utf8编码,u8前缀中u为小写字母 c++17才开始支持
string u8str = u8"中国";

C++20中增加了 char8_t和 std::u8string对于 UTF-8提供支持.

// c++20开始支持 char8_t std::u8string
u8string u8str = u8"中国";string u8str = u8"中国"; // 在 C++20中不再支持,需要使用u8string。

2、编码转换

在C++标准提供的codecvt中,能够直接用于std::wstring_convert的只有三个:

std::codecvt_utf8,std::codecvt_utf16以及std::codecvt_utf8_utf16。

可见,标准只支持UTF族的字符编码。为了获取其它字符编码的codecvt,需要使用std::codecvt_byname,这个类可以通过字符编码的名称来创建一个codecvt。

这看起来挺不错,但遗憾的是,字符编码的名称并没有统一的标准,各个平台的支持情况都不一样。通常使用系统自定义的转换函数进行转换。

// utf-8 to utf16std::wstring_convert< std::codecvt_utf8_utf16<char16_t>, char16_t >{}.from_bytes(str);std::wstring_convert< std::codecvt_utf8_utf16<char16_t>, char16_t >{}.to_bytes(str16);// utf-8 to utf32 std::wstring_convert< std::codecvt_utf8<char32_t>, char32_t >{}.from_bytes(str);std::wstring_convert< std::codecvt_utf8<char32_t>, char32_t >{}.to_bytes(str32);// utf-8 to wstringstd::wstring_convert< std::codecvt_utf8<wchar_t>, wchar_t >{}.from_bytes(str);std::wstring_convert< std::codecvt_utf8<wchar_t>, wchar_t >{}.to_bytes(wstr);

std::wstring_convert 与 std::codecvt_utf8 在 C++17 中已经被标记为弃用。可以使用ICU4C库进行编码转换。

International Components for Unicode (ICU) - Win32 apps | Microsoft Docs

On Windows 10 Version 1709 and above, you should include the combined header instead:#include <icu.h>  ,  link :  icu.lib

五、数值表示和转换

1、不同进制的数值表示

2进制、8进制,16进制表示175:

int a1 = 0b1010'1111;
int a2 = 0b10101111; //二进制
int a3 = 0xaf;  //16进制
int a4 = 0257; //8进制long long a5; //至少64位的长整形

2、字符串和数值类型转换

std::string s{"123"};int i{ std::stoi(s) };

string 头文件提供了 stol()、stoll() 、stoul()、stoull()、stof()、stod()  和 stold() 函数,它们都包含在 std 名称空间中,可分别将字符串转换为 long、long long、unsigned long、unsigned long long、float、double 和 long double 类型。

c++11标准增加了全局函数std::to_string:

string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);std::string pi = std::to_string(3.1415926);  

六、字面量

1、字符串字面量

  • 对于raw(未处理的)字符串字面量是形式是R"定界()定界",其中定界是可选的,因为默认()是一对定界符,这里的额外的定界是为了标记定界括号用的,例如:

    char str[] = R"((123)")";
    

    上面的由于无定界符所以在123后面的)"会被当作字符串结尾,但是存在定界符:

    char str[] = R"...((123)")...";char32_t str3[] = UR"...((123)")...";
    

    此时未出理的字符串内容就是(123)"了,因为标记范围已经明确.

2、浮点字面量

概要:十六进制浮点数字面量
注释:具有十六进制底数和十进制指数的浮点数字面量:0xC.68p+2、0x1.P-126。C语言自从C99开始就支持这种语法, printf的%a可以输出这种形式的浮点数。

后缀 若存在,则为 fFl 或 L 之一。后缀决定浮点字面量的类型:

  • (无后缀)定义 double
  • f F 定义 float
  • l L 定义 long double
数位间可插入作为分隔符的单引号('),在编译时忽略它们。 (C++14 起)

浮点数类型有如下三种:

类型 所占字节数
float 4
double 8
long double 8

浮点数字面量的默认识别类型是double,可以通过F、L后缀将一个浮点数字面量转化为其他类型。

使用十进制科学计数法,表示浮点字面量的值是有效数字乘以 10 的 指数 次幂。123e4 的数学含义是 123×104

若浮点字面量以字符序列 0x 或 0X 开始,则该浮点字面量是十六进制浮点字面量。否则,它是十进制浮点字面量

对于十六进制浮点字面量,其有效数字被解释为十六进制有理数,而指数的 数字序列 被解释成有效数字要放大的 2 的整数幂次。

double d = 0x1.2p3; // 十六进制分数 1.2(十进制 1.125)的 2^3 倍,即 9.0
(C++17 起)

示例: 0xC.68p+3;  = (12  + 6/16 + 8/16/16 )*2^3

浮点数转化为二进制有它自己的规则:
1.浮点数的整数部分,仍按照整数转二进制的规则,除2取余(直到余数为0),倒序排列
2.浮点数的小数部分,采用乘2取整(直到小数部分为0),正序排列
例如123.45整数部分和小数部分分别转化为二进制串:

可见,整数部分一定能完全转化为二进制串(余数总会归0),但小数部分不一定能完全转化为二进制串(小数部分不一定归0)。因此,计算机是不能完全表示浮点数的(显然当小数部分是1 / 2^n时可以完全转化,但仍要考虑存储宽度的问题,因为可能要很多位才能完全表示这个小数部分),这就涉及到表示的浮点数的精度问题。
实际上一个浮点数通过上述方法分别计算出整数部分和小数部分二进制串之后并不能直接存储到计算机中,因为这样至少要能标志小数点的位置。
实际存储到计算机中的浮点数二进制串是经过IEEE754标准生成的,二进制串包括符号位、指数部分、位数部分,具体可以参考IEEE754标准。

七、新容器

std::array            传统数组

std::forward_list   单向链表

std::unordered_map   哈希表

std::unordered_set    哈希集合

八、C++20的文本格式化

文本格式化库提供 printf 函数族的安全且可扩展的替用品。有意使之补充既存的 C++ I/O 流库并复用其基础设施。C++20提供了std::format全局函数,提供媲美Python的文本格式化支持。需要包含头文件 : #include <format>。

1、函数重载定义

template<class... Args>
std::string format(std::string_view fmt, const Args&... args);template<class... Args>
std::wstring format(std::wstring_view fmt, const Args&... args);template<class... Args>
std::string format(const std::locale& loc, std::string_view fmt, const Args&... args);template<class... Args>
std::wstring format(const std::locale& loc, std::wstring_view fmt, const Args&... args);

按照格式字符串 fmt 格式化 输出参数 args ,并返回作为 string 的结果。 loc 若存在,则用于本地环境特定的格式化。

输入参数说明:
fmt - 表示格式字符串的字符串视图。

格式字符串由以下内容组成:

  • 通常字符(除了 { 与 } ),它们被不加修改地复制到输出
  • 转义序列 {{ 与 }} ,它们在输出中被分别替换成 { 与 }
  • 替换域

每个替换域拥有下列格式: {arg-id:格式说明}

(可选) arg-id ,一个非负数
(可选) 冒号( : )后随格式说明

arg-id 指定用于格式化其值的 args 中的参数的下标;若省略 arg-id ,则按顺序使用参数。格式字符串中的 arg-id 必须全部存在或全部被省略,混合手动和自动指定下标是错误。
格式说明由对应参数特化的 std::formatter 定义。

  1. 对于基本类型和标准字符串类型,格式说明为标准格式说明
  2. 对于标准日期和时间类型,格式说明为 chrono 格式说明
  3. 对于用户定义类型,格式说明由用户定义的 std::formatter 特化决定

args… - 要格式化的参数

loc - 用于本地环境特定格式化的 std::locale

返回值
保有格式化结果的 string 对象。

异常
若 fmt 对于提供的参数不是合法的格式字符串则抛出 std::format_error 。并且会传播任何格式化器所抛的异常。
注意,提供多于格式字符串所要求的参数不是错误:

std::format("{} {}!", "Hello", "world", "something");
// OK :产生 "Hello world!"

简单示例:

#include <format>
#include <cassert>
int main() {std::string message = std::format("The answer is {}.", 42);assert( message == "The answer is 42." );
}

标准格式说明:

基本格式:


填充与对齐(可选) 符号(可选) #(可选) 0(可选) 宽度(可选) 精度(可选) L(可选) 类型(可选)


符号 、 # 及 0 选项仅当使用整数或浮点显示类型时合法。

填充与对齐

一个可选的填充字符(可为任何 { 或 } 外的的字符),后随对齐选项 < 、 > 、 ^ 之一。对齐选项的意义如下:

< :强制域在可用空间内左对齐。这在使用非整数非浮点显示类型时为默认。
> :强制域在可用空间内右对齐。这在使用整数或浮点显示类型时为默认。
^ :强制域在可用空间中央,通过在值的前面插入n/2向下取整个字符,后面插入n/2向上取整个字符,其中 n 是待插入的总字符数。

char c = 120;
auto s0 = std::format("{:6}", 42);    // s0 的值为 "    42"
auto s1 = std::format("{:6}", 'x');   // s1 的值为 "x     "
auto s2 = std::format("{:*<6}", 'x'); // s2 的值为 "x*****"
auto s3 = std::format("{:*>6}", 'x'); // s3 的值为 "*****x"
auto s4 = std::format("{:*^6}", 'x'); // s4 的值为 "**x***"
auto s5 = std::format("{:6d}", c);    // s5 的值为 "   120"
auto s6 = std::format("{:6}", true);  // s6 的值为 "true  "

符号、 # 与 0

符号 选项能为下列之一:

  • + :指示符号应该一同用于非负数和负数。在非负数的输出值前插入 + 号。
  • - :指示符号应该仅用于负数(这是默认行为)。
  • 空格:指示应对非负数使用前导空格,而对负数使用负号。

负零被当作负数。符号 选项应用于浮点无穷大和 NaN 。

double inf = std::numeric_limits<double>::infinity();
double nan = std::numeric_limits<double>::quiet_NaN();
auto s0 = std::format("{0:},{0:+},{0:-},{0: }", 1);   // s0 的值为 "1,+1,1, 1"
auto s1 = std::format("{0:},{0:+},{0:-},{0: }", -1);  // s1 的值为 "-1,-1,-1,-1"
auto s2 = std::format("{0:},{0:+},{0:-},{0: }", inf); // s2 的值为 "inf,+inf,inf, inf"
auto s3 = std::format("{0:},{0:+},{0:-},{0: }", nan); // s3 的值为 "nan,+nan,nan, nan"

# 选项导致将替用形式用于转换。

  • 对于整数类型,使用二进制、八进制或十六进制显示类型时,替用形式插入前缀( 0b 、 0 或 0x )到输出值中,若有符号则于符号(可为空格)前,否则于输出值前。
  • 对于浮点类型,替用形式导致有限值的转换结果始终含有小数点字符,即使其后无数位。正常情况下,小数点字符仅若有数位后随它才出现于转换结果。另外,对于 g 与 G 转换,不从结果移除尾随的零。

0 选项以前导零填充域(后随任何符号或底)到域宽,除了应用到无穷大或 NaN 时。若 0 字符与对齐选项一同出现,则忽略 0 字符。

char c = 120;
auto s1 = std::format("{:+06d}", c);   // s1 的值为 "+00120"
auto s2 = std::format("{:#06x}", 0xa); // s2 的值为 "0x000a"
auto s3 = std::format("{:<06}", -42);  // s3 的值为 "-42   " (因 < 对齐忽略 0 )

宽度与精度

宽度 为正十进制数,或嵌套的替换域( {} 或 {n} )。宽度若存在则指定最小域宽。

精度 为点( . )后随非负十进制数或嵌套的替换域。此域指示精度或最大域大小。它仅能用于浮点与字符串类型。对于浮点类型,此域指定格式化精度。对于字符串类型,它提供要复制到输出的字符串前缀的估计宽度(见后述)的上界。对于以 Unicode 编码的字符串,复制到输出的文本是整个扩展字素集群的,使得估计宽度不大于精度的最长前缀。

若 宽度 或 精度 中使用嵌套的替换域,而对应的参数不是整数类型,或为负,或对于 宽度 为零,则抛出 std::format_error 类型异常。

float pi = 3.14f;
auto s1 = std::format("{:10f}", pi);           // s1 = "  3.140000" (宽度 = 10 )
auto s2 = std::format("{:{}f}", pi, 10);       // s2 = "  3.140000" (宽度 = 10 )
auto s3 = std::format("{:.5f}", pi);           // s3 = "3.14000" (精度 = 5 )
auto s4 = std::format("{:.{}f}", pi, 5);       // s4 = "3.14000" (精度 = 5 )
auto s5 = std::format("{:10.5f}", pi);         // s5 = "   3.14000"// (宽度 = 10 ,精度 = 5 )
auto s6 = std::format("{:{}.{}f}", pi, 10, 5); // s6 = "   3.14000"// (宽度 = 10 ,精度 = 5 )auto b1 = std::format("{:{}f}", pi, 10.0);     // 抛出:宽度不是整数类型
auto b2 = std::format("{:{}f}", pi, -10);      // 抛出:宽度为负
auto b3 = std::format("{:.{}f}", pi, 5.0);     // 抛出:精度不是整数类型

对于字符串类型,宽度定义为适合将它显示到终端的估计列位置数值。

就宽度计算目的,假设字符串用实现定义的编码。宽度计算的方法是未指定的,但对于以 Unicode 的字符串,实现应该估计字符串的宽度为其扩展字素集群中首个码位的估计宽度之和。若 Unicode 码位在下列范围内,则估计宽度为 2 ,否则为 1 :

  • U+1100 - U+115F
  • U+2329 - U+232A
  • U+2E80 - U+303E
  • U+3040 - U+A4CF
  • U+AC00 - U+D7A3
  • U+F900 - U+FAFF
  • U+FE10 - U+FE19
  • U+FE30 - U+FE6F
  • U+FF00 - U+FF60
  • U+FFE0 - U+FFE6
  • U+1F300 - U+1F64F
  • U+1F900 - U+1F9FF
  • U+20000 - U+2FFFD
  • U+30000 - U+3FFFD
auto s1 = std::format("{:.^5s}",   "												

C++11~C++20 备忘录相关推荐

  1. 【历史上的今天】11 月 20 日:微软发布 Windows 1.0;Lotus Notes 发明者出生;奔腾4 诞生

    整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来. 今天是 2022 年 11 月 20 日,在 27 年前的今天,世界上首例人造心脏移植手术成功:一名退休的电影制片人成为世 ...

  2. c语言数据结构线性表LA和LB,数据结构(C语言版)设有线性表LA(3,5,8,110)和LB(2,6,8,9,11,15,20)求新集合?...

    数据结构(C语言版)设有线性表LA(3,5,8,110)和LB(2,6,8,9,11,15,20)求新集合? 数据结构(C语言版)设有线性表LA(3,5,8,110)和LB(2,6,8,9,11,15 ...

  3. 假设用于通信的电文由字符集{a,b,c,d,e,f,g}中的字母构成。 它们在电文中出现的频度分别为{0.31,0.16,0.10,0.08,0.11,0.20,0.04}。【MOOC答案】

    目   录 1.题目 2.答案and详细题解过程 1)为这7个字母设计哈夫曼编码: 1.1.答案 1.2.详细题解过程 2)为这7个字母设计等长编码,至少需要几位二进制数?[3位] 2.1.答案 2. ...

  4. 分享Silverlight/WPF/Windows Phone一周学习导读(11月14日-11月20日)

    分享Silverlight/WPF/Windows Phone一周学习导读(11月14日-11月20日) 本周Silverlight学习资源更新 Silverlight App.xaml用途 Jaso ...

  5. 吃鸡11月15服务器维护,绝地求生11月20日维护到几点 11.20吃鸡更新维护公告

    绝地求生在11月20日这天官方宣布开启停机的更新维护,此次的更新时间为8个小时,可以说非常长了,重点是第五赛季第二轮的更新内容,下面就来为大家分享一下绝地求生的更新维护公告. [正式服维护公告] 我们 ...

  6. VDI SolutionTrack - 上海站:11月20日

    如果您无法正常显示此邮件,请点击这里 [url]http://www.chnteamax.com/11.3/shanghai/edm.html[/url] SolutionTrack - Virtua ...

  7. 深圳百元赠送话费11月20日前启动充

    [深圳商报讯](记者 刘金玉)为了庆祝深圳经济特区建立30周年,民族吹奏乐器,让广大市民分享特区30华诞的喜悦,深圳市政府联合运营商开展了向每位市民回馈100元话费的活动.记者昨日从市科工贸信委获悉, ...

  8. csgo中国上海服务器因维护,2019CSGO亚洲邀请赛11月20日战火重燃 再临上海

    由完美世界主办的2019CSGO亚洲邀请赛将于11月20日再度在上海重燃战火!本次CSGO亚洲邀请赛共有八支参赛战队,他们是EG.AVANGAR.Mouz.G2.ENCE.Mibr.Tyloo和VG, ...

  9. 2019年11月20日笔记

    2019年11月20日笔记 DIP PhotoShop 数字图像处理用途 AI设计原理 编程 哲学 编程工具 DIP DIP全称Digital Image Processing(数字图像处理) 每张图 ...

最新文章

  1. 如何让弹窗不影响主界面_如何压缩视频大小不影响画质
  2. java新手笔记1 Hello World!
  3. API设计原则 - Qt官网的设计实践总结
  4. quill鼠标悬浮 出现提示_jQuery实现鼠标悬停显示提示信息窗口的方法
  5. 贴一段Jenkins的自动发布脚本
  6. 使用爬虫刷blog访问量 随机代理IP 随机user_agent
  7. 调用http_【学习充电】直观讲解一下 RPC 调用和 HTTP 调用的区别!
  8. Android CountDownTimer示例
  9. 微软打碎了周鸿祎的如意算盘
  10. 看漫画学python电子书-看漫画学Python:有趣、有料、好玩、好用(全彩版)
  11. 装修报价不担心被骗 避免家装陷阱报价揭密
  12. poj 3295 Tautology【离散数学之重言式】
  13. Flak 解析json数据不完整?
  14. 关于scipy库里面的DCT离散余弦变换函数
  15. 分享自己在uniapp开发中用的css样式
  16. Pycharm专业版下载、安装、与Anaconda配置、中文化及字体设置、Cracking(自行翻译)方法
  17. 一.图像处理系统MATLAB实现(GUI界面)
  18. COS操作 java实现
  19. Windows 11家庭版
  20. 【时间序列】N-BEATS:对可解释时序预测的神经基础扩展分析

热门文章

  1. 安卓手机主题软件_超小型软件,安卓手机必备
  2. 小学数学题的python实现
  3. 第一部分 思科九年 一(15)
  4. dreawever与php做网页,如何用dreamware制作网页
  5. 熊市亏钱了?不用怕,ET钱包带你领糖果薅羊毛
  6. HTB-Templated
  7. RegExp 使用说明
  8. flutter 布局裁剪及实现微信聊天消息气泡组件
  9. java UDP/IP
  10. plc中int数据类型范围_[PLC]S7-300的数据类型