《现代C++语言核心特性解析》阅读笔记

这段时间因为个人兴趣爱好一直在网上搜寻有没有一本有关于现代C++相关的书籍。为什么我会需要一本这样的书籍呢?因为C++标准委员会只制定标准,但不会强制要求你该怎么做,而各家编译器也是自己支持自己的。这时候对于我来说就需要一本专门讨论现代C++的数据告诉我现代C++有哪些特性,该怎么用,诞生的原因以及编译器的支持情况。毕竟没人会希望自己写的优美的、现代化的、简洁的代码因为编译器的支持问题而需要修改回旧版的写法。

字符类型char16_t与char32_t

C++对于Unicode的支持很有限,虽然它在C++11标准中添加了新的字符类型char8_t和char16_t与char32_t用于对应Unicode字符集中的UTF-8、UTF-16和UTF-32两种编码方式,但是C++不提供std::cout对于Unicode字符集的支持。而且C++20也不支持将与上述字符类型对应的字符串u8string、u16string和u32string转换成string类型,虽然在C++17中你可以将任何 UTF-8 数据视为“字符”数据,这使得可以使用 std::regex、std::fstream、std::cout 等而不会丢失的性能。按照标准委员会的说法这是因为市面上有很多用于处理UTF的库,但就我个人的看法这只会导致C++高版本中大家都不使用该特性。

内联和嵌套命名空间

内联和嵌套命名空间是个好东西,就我个人的看法所有能有避免嵌套写法的都是好东西,不过相对来说内联命名空间的重要性会比嵌套命名空间大。因为内联命名空间可以帮助库作者无缝切换代码版本而无需库的使用者参与。

auto占位符

讨论auto的时候需要知道它和delctype的区别。

先了解auto的推导规则:

  1. 如果auto声明的变量是按值初始化,则推导出的类型会忽略cv限定符
  2. 使用auto声明变量初始化时,目标对象如果是引用,则引用属性会被忽略
  3. 使用auto和万能引用&&声明变量时,对于左值会将auto推导为引用类型。
  4. 使用auto声明变量,如果目标对象是一个数组或者函数,则auto会被推导为对应的指针类型
  5. 当auto关键字与列表初始化结合时:
    1. 直接使用列表初始化,列表中必须为单元素,否则无法编译,auto类型被推导为单元素的类型。
    2. 用等号加列表初始化,列表中可以包含单个或多个元素,auto类型被推导为std::initializer_list<T>,其中T是元素类型。

再观察decltype(e)(其中e的类型为T)的推导规则:

  1. 如果e是一个未加括号的标识符表达式(结构化绑定除外)或者未加括号的类成员访问,则decltype(e)推断出的类型是e的类型T。如果不存在这样的类型,或者e是一组重载函数,则无法进行推导。
  2. 如果e是一个函数调用或者仿函数调用,那么decltype(e)推断出的类型是其返回值的类型。
  3. 如果e是一个类型为T的左值,则decltype(e)是T&。
  4. 如果e一个类型为T的将亡值,则decltype(e)是T&&。
  5. 除去以上情况,则decltype(e)是T。

通过对auto和decltype推导规则的学习,可以发现auto相比于decltype会忽略cv限定符,忽略引用属性。因此decltype相比于auto在很大程度上加强了C++的泛型能力。所以在C++14中引入了decltype(auto)用来告诉编译器用decltype的推导表达式规则来推导auto。

原文地址:https://www.cnblogs.com/GodZhuan/p/15808454.html