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新增特性

相关推荐
QuantumStack6 分钟前
【C++ 真题】P1104 生日
开发语言·c++·算法
天若有情67317 分钟前
01_软件卓越之道:功能性与需求满足
c++·软件工程·软件
缘来是庄20 分钟前
设计模式之访问者模式
java·设计模式·访问者模式
whoarethenext22 分钟前
使用 C++/OpenCV 和 MFCC 构建双重认证智能门禁系统
开发语言·c++·opencv·mfcc
Bug退退退1231 小时前
RabbitMQ 高级特性之死信队列
java·分布式·spring·rabbitmq
梵高的代码色盘1 小时前
后端树形结构
java
代码的奴隶(艾伦·耶格尔)1 小时前
后端快捷代码
java·开发语言
虾条_花吹雪1 小时前
Chat Model API
java
双力臂4041 小时前
MyBatis动态SQL进阶:复杂查询与性能优化实战
java·sql·性能优化·mybatis
Jay_5151 小时前
C++多态与虚函数详解:从入门到精通
开发语言·c++