【C++11】 列表初始化 auto 范围for 新增关键字 新增容器

简介: 【C++11】 列表初始化 auto 范围for 新增关键字 新增容器

1 列表初始化

由c语言的规则我们知道:一般只有数组才会支持用{}初始化,但是C++11新语法规定我们不仅可以用{}初始化各种对象(内置类型和自定义类型),还可以不加上前面的=符号(一般不建议这样使用,可读性不好),比如下面的用法:

struct Point
{
 int _x;
 int _y;
};
int main()
{
 int x1 = 1;
 int x2{ 2 };
 int array1[]{ 1, 2, 3, 4, 5 };
 int array2[5]{ 0 };
 Point p{ 1, 2 };
 // C++11中列表初始化也可以适用于new表达式中
 int* pa = new int[4]{ 0 };
 return 0;
}

但是这样初始化的原理是什么呢?其实在C++11中又增加了一个新的类:initializer_list

【initializer_list的介绍文档】

initializer_list使用场景:

std::initializer_list一般是作为构造函数的参数,C++11对STL中的不少容器就增加std::initializer_list作为参数的构造函数,这样初始化容器对象就更方便了。也可以作为operator=的参数,这样就可以用大括号赋值像vector,list等容器我们可以直接用{}赋值。

2d117b59c3c346bbaa5f10d10f6d705a.png

比如下面这种用法:

int main()
{
 vector<int> v = { 1,2,3,4 };
 list<int> lt = { 1,2 };
 // 这里{"sort", "排序"}会先初始化构造一个pair对象
 map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
// 使用大括号对容器赋值
v = {10, 20, 30};
 return 0;

2 auto && 范围for

这个语法我们早在讲解C++入门的时候就已经讲解了,感兴趣的老哥可以点击下面链接:【C++入门基础】

3 新增关键字

3.1 decltype

关键字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;
}

其实上面的这些场景用auto也可以很好的代替,但是下面的情况就不能够用auto代替了:

vector<decltype(x*y)>,由于vector中需要的是具体的类型,所以无法使用auto.

3.2 default

假设你要使用某个默认的函数,但是因为一些原因这个函数没有默认生成。比如:我们提供了自己写的默认构造,编译器就不会生成默认构造了。但是我们可以用default强制编译器生成。

class Person
{
public:
 Person(const char* name = "", int age = 0)
 :_name(name)
 , _age(age)
 {}
 Person(const Person& p)
 :_name(p._name)
 ,_age(p._age)
 {}
 Person() = default;
private:
 bit::string _name;
 int _age;
};

但是上面程序好像并没有实际价值,在学习了右值引用和移动语义后我们可以强制编译器生成默认的移动构造等等。

3.3 delete

如果想要限制某些默认函数的生成,在C++98中,我们应该怎么做?

将该函数设置成private,并且只声明补丁,这样只要其他人想要调用就会报错。

但是C++11提供了更加简易的方式:用delete关键字指定函数即可。

用法:

class Person
{
public:
 Person(const char* name = "", int age = 0)
 :_name(name)
 , _age(age)
 {}
 Person(const Person& p) = delete;
private:
 bit::string _name;
 int _age;
};
int main()
{
 Person s1;
 Person s2(s1);//报错
 return 0;
}

3.4 final与override

这两个关键字博主在继承与多态的文章详细介绍过,有兴趣的老哥可以移步:

【继承与多态】

4 总结

总的来说本次介绍的新语法还是挺简单的,都是一些基础的内容,C++11系列还有内容没有更新完,我们下次再见啦!! ❤️ ❤️❤️

目录
相关文章
|
1月前
|
自然语言处理 编译器 C语言
【C++ 20 新特性】参数包初始化捕获的魅力 (“pack init-capture“ in C++20: A Deep Dive)
【C++ 20 新特性】参数包初始化捕获的魅力 (“pack init-capture“ in C++20: A Deep Dive)
40 0
|
1月前
|
设计模式 程序员 C++
【C++ 泛型编程 高级篇】C++模板元编程:使用模板特化 灵活提取嵌套类型与多容器兼容性
【C++ 泛型编程 高级篇】C++模板元编程:使用模板特化 灵活提取嵌套类型与多容器兼容性
259 2
|
4天前
|
编译器 C++
【C++基础(八)】类和对象(下)--初始化列表,友元,匿名对象
【C++基础(八)】类和对象(下)--初始化列表,友元,匿名对象
|
10天前
|
编译器 C++
C++编程之美:探索初始化之源、静态之恒、友情之桥与匿名之韵
C++编程之美:探索初始化之源、静态之恒、友情之桥与匿名之韵
21 0
|
11天前
|
索引 容器
06-python数据容器-list列表定义/list的10个常用操作/列表的遍历/使用列表取出偶数
06-python数据容器-list列表定义/list的10个常用操作/列表的遍历/使用列表取出偶数
|
18天前
|
编译器 C语言 C++
【C++】C++入门第一课(c++关键字 | 命名空间 | c++输入输出 | 缺省参数)
【C++】C++入门第一课(c++关键字 | 命名空间 | c++输入输出 | 缺省参数)
|
19天前
|
存储 程序员 编译器
C++注释、变量、常量、关键字、标识符、输入输出
C++注释、变量、常量、关键字、标识符、输入输出
|
20天前
|
编译器 C语言 C++
【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例
【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例
|
算法 程序员 C语言
【C++ 迭代器】深入探讨 C++ 迭代器:标准与自定义容器中的 begin() 和 cbegin()
【C++ 迭代器】深入探讨 C++ 迭代器:标准与自定义容器中的 begin() 和 cbegin()
50 0
|
3天前
|
存储 Kubernetes Docker
Kubernetes(K8S)集群管理Docker容器(概念篇)
Kubernetes(K8S)集群管理Docker容器(概念篇)

热门文章

最新文章