前言
本文用来记录一下cpp11版本新加入的一些特性,包括lambda、左右值引用、移动拷贝、移动构造
统一的列表初始化
{}初始化
cpp98
其实在98版本中就加入了{}初始化的方法,但只能用于初始化数组或者结构体的元素,需要添加=
struct Point
{
int _x;
int _y;
};
int main()
{
int array1[] = { 1, 2, 3, 4, 5 };
int array2[5] = { 0 };
Point p = { 1, 2 };
return 0;
}
cpp11
在11的版本种,扩大了{}的使用范围,使其可以用于初始化所有的内置类型和用户自定义类型(好🐂),并且=可以不添加
创建内置类型
这里提示一下:
new可以和{}结合使用
int* pa = new int[8]{ 0 };
创建对象
创建对象时,也可以用{}来调用对象的构造函数
class Date
{
public:
Date(int year, int month, int day)
:_year(year)
, _month(month)
, _day(day)
{
cout << "Date(int year, int month, int day)" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1(2022, 1, 1); // old style
// C++11支持的列表初始化,这里会调用构造函数初始化
Date d2{ 2022, 1, 2 };
Date d3 = { 2022, 1, 3 };
return 0;
}
std::initializer_list
先来看一段代码,大家可以自己运行一下
int main()
{
// the type of il is an initializer_list
auto il = { 10, 20, 30 };
cout << typeid(il).name() << endl;
return 0;
}
编译器给出的是
class std::initializer_list<int>
声明
auto
感觉大家学习的cpp11的第一个新特性就是auto,很实用
auto用于实现自动类型推断。进行显式初始化,让编译器将定义对象的类型设置为初始化值的类型
decltype
这个关键字将变量的类型声明为表达式指定的类型
template<class T1, class T2>
void F(T1 t1, T2 t2) {
decltype(t1 * t2) ret;
cout << typeid(ret).name() << endl;
}
int main()
{
const int x = 1;
double y = 2.2;
decltype(x * y) ret; // ret的类型是double
decltype(&x) p;
// p的类型是int*
cout << typeid(ret).name() << endl;
cout << typeid(p).name() << endl; F(1, 'a');
return 0;
}
nullptr
由于C++中NULL被定义成字面量0,这样就可能回带来一些问题,因为0既能指针常量,又能表示整形常量。所以出于清晰和安全的角度考虑,C++11中新增了nullptr,用于表示空指针。
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
结束
本文只是引入,下文要介绍左值、右值引用、完美转发这些知识点。
下篇文章见