【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系列还有内容没有更新完,我们下次再见啦!! ❤️ ❤️❤️

目录
相关文章
|
6天前
|
C++ 容器
C++中自定义结构体或类作为关联容器的键
C++中自定义结构体或类作为关联容器的键
13 0
|
8天前
|
C++ 容器
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——AVL树
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——AVL树
18 5
|
6天前
|
存储 C++ 索引
|
11天前
|
存储 安全 编译器
C++入门 | auto关键字、范围for、指针空值nullptr
C++入门 | auto关键字、范围for、指针空值nullptr
31 4
|
27天前
|
存储 C++ 容器
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
37 5
|
4天前
|
安全 编译器 容器
C++STL容器和智能指针
C++STL容器和智能指针
|
6天前
|
存储 缓存 NoSQL
【C++】哈希容器
【C++】哈希容器
|
6天前
|
存储 编译器 C++
【C++关键字】auto的使用(C++11)
【C++关键字】auto的使用(C++11)
|
8天前
|
关系型数据库 C++ 容器
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——红黑树
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——红黑树
15 0
|
1月前
|
安全 程序员 C++
C++一分钟之-C++中的并发容器
【7月更文挑战第17天】C++11引入并发容器,如`std::shared_mutex`、`std::atomic`和线程安全的集合,以解决多线程中的数据竞争和死锁。常见问题包括原子操作的误用、锁的不当使用和迭代器失效。避免陷阱的关键在于正确使用原子操作、一致的锁管理以及处理迭代器失效。通过示例展示了如何安全地使用这些工具来提升并发编程的安全性和效率。
21 1

热门文章

最新文章