C++11 新特性

原文 https://www.cnblogs.com/linuxAndMcu/p/11600553.html

1. nullptr

(1) 作用:nullptr 的类型为 nullptr_t,能够隐式地转换为任何指针的类型,能和他们进行相等或者不等的比较。

简单说,nullptr目的是为了区分 空指针NULL 和 0。

(2) 解释:传统C++ 把NULL和0视为同一种东西,这样会导致出现违反直观的情况。比如:

cpp 复制代码
void foo(char *); //构造函数char
void foo(int);    //构造函数int
main() {
    char* ch = NULL;    //NULL被视为0
    foo(ch);    //调用 构造函数int,而不是调用 构造函数char,违反直观。
}

c++11 改用 char* ch = nullptr 之后,就会调用构造函数char,避免违法直观。

2. 类型推导

2.1 auto关键字

(1) 作用:可以让编译器自动分析初始值来判断变量所属的类型。必须确定初始值类型。

(2) 解释:典型的使用例子是迭代器:

cpp 复制代码
//c++98:
for(vector<int>::const_iterator itr = vec.cbegin(); itr != vec.cend(); ++itr)
//c++11: 
for(auto itr = vec.cbegin(); itr != vec.cend(); ++itr);
2.2 decltype关键字

(1) 作用:自动分析表达式判断它的类型,但不会去计算表达式的值。

(2) 解释:

cpp 复制代码
auto x = 1;    //自动推导为 int
auto y = 2;
decltype(x+y) z;    //也自动推导为 int
2.3 auto 和 decltype 的区别

(1) 执行时间不同:

auto: 执行在程序运行期间。

decltype:执行在程序编译期间。(与sizeof()一样)

(2) 推导逻辑不同:

auto:通过编译器计算变量的初始值来推导类型;如果初始化语句中存在多个表达式且类型不相同时,会推导出"最宽泛"的类型。

decltype:分析表达式的结果来推导类型,但又不会执行将表达式的值计算出来。

(3) 顶层const处理逻辑不同:

auto: 会忽略顶层const,比如:const int m = 10; auto d = m; //d 的类型是int 不带 const

decltype:不会忽略顶层const。

(4) 推导获得引用类型逻辑不同:

auto:不会推导获得引用类型。

decltype:多层括号decltype((表达式)) ,返回的就是引用。 表达式是左值也会获得引用类型。

(5) 使用场景不同:

auto:适合简单的类型推导,比如迭代器 和 模板编程中简化模板函数或模板类的定义。

decltype:复杂表达式的类型推导,避免不必要的类型转换,特别是涉及到const和引用。

(6) 参考文章:

C++11中auto与decltype的区别与联系深入解析_auto和decltype区别-CSDN博客

auto 和 decltype的区别_decltype和auto的区别-CSDN博客

2.4 拖尾返回类型、auto 与 decltype 配合

(1) 作用:推导函数模板的返回类型。

(2) 解释: decltype(x+y) add(T x, U y); 这种自动推导函数返回类型的写法,会编译错误。因为编译器在编译时不能确定x和y的类型。所以c++11引入了拖尾返回类型" -> " ,如下代码所示:

cpp 复制代码
template<typename T, typename U>
auto add(T x, U y) -> decltype(x+y) {    //拖尾返回类型
    return x+y;
}

这样就 避免了 编译期间需要确定模板参数的类型,获得自动推导能力。

3. 区间迭代 - 基于范围的 for 循环

(1) 作用:引入了基于范围的迭代写法,: key : array

(2) 解释: 代码如下:

cpp 复制代码
c++98:
for(std::vector<int>::iterator i = arr.begin(); i != arr.end(); ++i) {
    std::cout << *i << std::endl;
}
c++11:
for(auto i : arr) {    
    std::cout << i << std::endl;
}

4. 列表 初始化

(1) 作用:统一普通数组、POD(plain old data)、类对象的初始化格式: A a = {x} 或 A a {x}。 有没有 赋值符号 = 都可以。

(2) 解释:代码如下:

cpp 复制代码
// 普通数组
int i_arr[3] = { 1, 2, 3 };
// POD类型:结构体
struct A
{
    int x;
    struct B
    {
        int i;
        int j;
    } b;
};
A a = { 1, { 2, 3 } };
// 类对象
class Foo
{
    public:
    Foo(int) {}
    Foo(const Foo &);
}  
Foo a = {123}; //调用构造函数 Foo(int) {}

5. 模板增强

5.1 外部模板

(1) 作用:显式的告诉编译器何时进行模板的实例化,避免重复实例化而导致的编译时间增加。

(2) 解释:传统 C++ 中,只要在每个编译文件中遇到被完整定义的模板,都会实例化。这样会重复实例化,导致编译时间增加。

C++11 引入了外部模板 extern,能够显式地告诉编译器何时进行模板的实例化。代码如下:

cpp 复制代码
template class std::vector<bool>;           // 强行实例化
extern template class std::vector<double>;  // 不在该编译文件中实例化模板
5.2 尖括号 ">"
相关推荐
Zzj_tju4 分钟前
Java 从入门到精通(九):集合框架入门,List、Set、Map 到底该怎么选?
java·开发语言·list
郝学胜-神的一滴6 分钟前
从线程栈到表达式求值:栈结构的核心应用与递归实现
开发语言·数据结构·c++·算法·面试·职场和发展·软件工程
姓蔡小朋友7 分钟前
Agent Skill设计模式
开发语言·javascript·设计模式
敲代码的嘎仔10 分钟前
Java后端开发——多线程面试题
java·开发语言·面试·多线程·八股·threadlocal·
sonnet-102910 分钟前
交换排序算法
java·c语言·开发语言·数据结构·笔记·算法·排序算法
NGC_661111 分钟前
深度解析 ConcurrentHashMap 1.8:put 与 get 核心流程全解
java·开发语言
需要点灵感17 分钟前
# 从身份证读卡到钉钉同步:C# WinForms企业级应用开发实战
开发语言·c#·钉钉
Joy T17 分钟前
【Web3】智能合约多环境部署架构:Mock机制与依赖注入实战
开发语言·架构·web3·区块链·php·智能合约·mock合约
三*一20 分钟前
基于 Turf.js 实现高精度多边形修整工具(模拟 ArcGIS 修整功能)
开发语言·前端·javascript·arcgis·maobox gl·turf.js
charlie11451419121 分钟前
通用GUI编程技术——Win32 原生编程实战(十八)——GDI 设备上下文(HDC)完全指南
开发语言·c++·ide·学习·visual studio·win32