C++11新增特性:列表初始化(std::initializer_list)& decltype、auto、nullptr、范围for

C++11新增特性:列表初始化(std::initializer_list)& decltype、auto、nullptr、范围for

  • 一、C++11新增统一初始化方式
    • [1.1 新增方式](#1.1 新增方式)
    • [1.2 初始化容器底层原理(std::initializer_list)](#1.2 初始化容器底层原理(std::initializer_list))
  • 二、新增声明
    • [2.1 decltype](#2.1 decltype)
    • [2.3 auto & nullptr & 范围for](#2.3 auto & nullptr & 范围for)

一、C++11新增统一初始化方式

1.1 新增方式

在C++98之前,{}一般被用于对数组或结构体元素的统一的列表初始值设定。

cpp 复制代码
struct Date
{
	int year;
	int monday;
	int day;
};

int main()
{
	int arr[5] = { 1, 2 ,3, 4, 5 };
	Date d = { 2024, 4 ,14 };
	return 0;
}

C++11扩大了初始化列表的使用范围,可用于所有的内置类型和自定义类型的初始化。并且在使用初始化列表时,等号可省略!!

cpp 复制代码
struct Date
{
	int year;
	int monday;
	int day;
};

int main()
{
	int arr[5]{ 1, 2 ,3, 4, 5 };//省略等号
	int i{ 1 };//初始化列表初始化内置类型,等价于int i = 1;或int i = {1};
	Date d{ 2024, 4 ,14 };//省略等号


	//C++中,初始化列表使用于new表达
	//本质上是用花括号中的值生成一个initializer_list对象,在调用对于的构造函数
	int* p = new int[5]{ 1, 2, 3 };
	return 0;
}

在C++11中,初始化类列表可用于容器默认构造函数和拷贝复制函数的统一初始值设定!!

【部分容器使用示例】:

cpp 复制代码
int main()
{
	//构造函数的初始值设定
	vector<int> v{ 1, 2, 3, 4, 5 };
	list<int> l{ 1, 2, 3, 4, 5 };
	map<string, string> m{  
		{"排序", "sort"},
		{"快排", "qsort"},
		{"水果", "fruits"}
	};

	//拷贝复制的初始值设定
	vector<int> v1;
	v1 = { 1, 3 ,5 ,7, 9 };
	list<int> l1;
	l1 = { 1 ,3 ,5, 7, 9 };
	return 0;
}

1.2 初始化容器底层原理(std::initializer_list)

std::initializer_list使用文档介绍

在C++11中,几乎所有的容器都新增了std::initializer_list作为参数的构造函数和赋值重载函数,这样初始化容器对象就更方便了。

【以vector为例】:


在执行vector<int> v{ 1, 2, 3, 4, 5 };该种语句时,编译器会用花括号中的值1, 2, 3, 4, 5构造出一个initializer_list对象。在通过调用容器中以initializer_list作为参数的默认构造函数来生成对象v(拷贝赋值函数工作原理一样)

更具体的说,编译器会通过迭代器依次获取initializer_list对象中的值,然后调用容器插入相关接口插入数据。

【下面以vector为例,实现过程】:

cpp 复制代码
namespace Myvector
{
	template<class T>
	class vector
	{
		typedef T* iterator;
	pubilc:
		vector<T>(initializer_list<T> l)
		{
			_start = new T[l.size()];
			_finish = _start + l.size();
			_endofstorage = _finish;

			iterator vit = _start;
			typename initializer_list<T>::iterator lit = l.begin();
			while (lit != l.end())
			{
				*vit++ = *lit++;
			}
		};

		vector<T>& operator=(initializer_list<T> l)
		{
			vector<T> tmp(l);
			std::swap(_start, tmp._start);
			std::swap(_finish, tmp._finish);
			std::swap(_endofstorage, tmp._endofstorage);
			return *this;
		}

	priceate:
		iterator _start = nullptr;
		iterator _finish = nullptr;
		iterator _endofstorage = nullptr;
	};
}

二、新增声明

2.1 decltype

在C++中,我们可以通过typeid().name()获取变量类型。但获取到的变量类型是以字符串形式显示的,无法作为类型定义变量继续使用。
 在C++11中,新增关键字decltypedecltype可以将变量类型声明为表达式的指定类型!!

cpp 复制代码
int main()
{
	int x = 2;
	double d = 4.2;
	cout << typeid(x).name() << "     " << typeid(d).name() << endl;
	//error typeid(x).name()获取到的信息是一个字符串
	//typeid(x).name() ret; 

	decltype(x * d) ret;//将ret声明为dobule
	cout << typeid(ret).name() << endl;
	return 0;
}

【运行结果】:

2.3 auto & nullptr & 范围for

有关C++11新增关键字和相关用法参考:CPP弥补了C的哪些缺陷及C++11新增特性

相关推荐
+72024 分钟前
如何在java中用httpclient实现rpc get请求
java·qt·rpc
秋野酱26 分钟前
基于 JavaWeb 的 SSM+Maven 微信小程序快递柜管理系统设计和实现(源码+文档+部署讲解)
java·微信小程序·maven·课程设计
你在我身后28 分钟前
Spring-JAVA
java·后端·spring
卓越软件开发1 小时前
Java计算机毕业设计基于SSM宠物美容信息管理系统数据库源代码+LW文档+开题报告+答辩稿+部署教程+代码讲解
java·课程设计·宠物
丁总学Java1 小时前
Cannot deserialize instance of java.lang.String out of START_ARRAY token
java·windows·python
+7201 小时前
Java 的 HttpClient 中使用 POST 请求传递参数
java·开发语言
lozhyf2 小时前
如何使用Spring boot框架实现图书管理系统
java·spring
WalkingWithTheWind~3 小时前
Linux搭建Nginx直播流媒体服务RTMP/RTSP转Http-flv视频浏览器在线播放/Vue/Java/ffmpeg
java·linux·nginx·ffmpeg·vue·http-flv·rtsp
FLZJ_KL3 小时前
【设计模式】【创建型模式】抽象工厂模式(Abstract Factory)
java·设计模式·抽象工厂模式