C++11新增语法:列表初始化
前言:
接下来我们将要讲解,相较于c++98,c++11中新增的语法以及如何使用~。我们首先来讲解:列表初始化。
下文预告:右值引用和移动语义
C++98中传统的{}
在c++98中的{},仅能初始化数组和结构体
#include<iostream>
#include<vector>
using namespace std;struct Point
{int _x;int _y;
};int main()
{//c++98的{},可以初始化数组和结构体int arr[] = { 1,2,3,4,5 };Point p = { 1,2 };
}
C++11中的{}
而在c++11中,c++11的目标是所有的初始化都可以通过{}进行初始化,{}初始化也叫做列表初始化
不论是内置类型、自定义类型都可以通过{}实现初始化。自定义类型的初始化本质是类型转换
在使用{}进行初始化时,可以省略 “=”
c++11的本意是实现初始化的大一统,在容器进行insert\push的时候,使用{}进行对象的构造就会很方便
#include<iostream>
#include<vector>
using namespace std;struct Date
{//构造函数Date(int year = 0, int month = 0, int day = 0):_year(year),_month(month),_day(day){cout << "构造" << endl;}//拷贝构造Date(const Date& date):_year(date._year), _month(date._month), _day(date._day){cout << "拷贝构造"<<endl;}int _year;int _month;int _day;
};int main()
{//c++11对所有初始化进行统一,既所有的初始化都可以通过:{}进行初始化//内置类型int a = { 5 };//自定义类型//这里本质是先构造临时对象,再拷贝构造给date//但是编译器会对 构造+拷贝构造进行优化 -> 优化为:构造(直接进行构造初始化)Date date = { 2025,4,17 };//这里引用的是临时对象。注:临时对象具有常性,所有必须要const引用const Date& d = { 2025,4,17 };//c++98本身支持单参数的类型转换,不用{}也可以Date date1 = { 2025 };Date date2 = 2025 ;//当使用{}进行初始化的时候也可以不用=int b { 5 };Date date3 { 2025,4,17 };Date date4 { 2025 };//比起有名对象和匿名对象传参,{}更加性价比vector<Date> v;v.push_back(date);v.push_back(Date());//走隐式类型转化v.push_back({ 2025,4,17 });
}
c++的语法是向上兼容的,所以看见98与11混用也要分得清
C++11中的std::initializer_list
上述讲到的{}初始化变量已经很方便了,但是初始化容器,例如vector还是不太方便。所以c++11为了初始化容器方便专门为我们提供了一个类模板,名叫:initializer_list。这个类的本质就是在底层开一个数组,将我们给出的值拷贝之后赋值给容器
当容器的构造函数支持initializer_list作为参数,就支持由多个参数构成的{x1,x2,x3,.....}进行初始化。
#include<iostream>
#include<vector>
#include<map>
using namespace std;int main()
{initializer_list<int> il = { 1,2,3,4 };//begin和end返回指向il中元素的指针//3个地址都相近,说明il存储在栈中int i = 0;cout << il.begin() << endl;cout << il.end() << endl;cout << &i << endl;//构造+拷贝构造 -> 优化为:直接构造vector<int> arr1 = { 1,2,3,4 };//传参:直接构造vector<int> arr2({ 1,2,3,4 });//引用临时对象const vector<int>& v = { 1,2,3,4 };//initializer_list与{}始化一起使用map<string, string> m = { {"abc","abc"},{"bcd","bcd"} };//同时也支持赋值操作arr1 = { 10,20,30,40 };
}
至此,所有的变量,所有的容器都可以使用{}进行初始化~