C++11新特性-初始化列表initializer_list

initializer_list、初始化列表、列表初始化

一、什么是列表初始化

使用一个花括号来初始化变量,表现形式如下:

1
2
3
4
5
// 第一种
std::vector<int> a{1,2,3,4,5};

// 第二种
std::vector<int> a = {1,2,3,4,5};

这里用到了一个新的类型,即 initializer_list,包含在标准库头文件中。

二、优点

1、在 C++11 以前,如果要初始化一个 vector,需要这样做

1
2
3
4
5
6
std::vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
a.push_back(4);
a.push_back(5);

很明显,使用列表初始化使得代码量少了很多,也更加的简洁优雅。

2、这种方式不仅仅可以用在 STL 中,也可以用于一般的内置类型。

1
2
int c{3};
int c = {3};

乍一看,这样做没什么优点,并没有变得更简洁,甚至还要多写两个花括号。但在 CppCoreGuideline 中,非常推荐这种写法。原因是有一个类型检查。

1
2
int c = 3.3; //这里会进行默认类型转换
int b = {3.3}; //这里编译器会给出警告(也有可能是错误)

理论上,这样的代码更加健壮。

三、自定义类型使用 initializer_list

C++11 也提供了方法,让用户可以在自定义类型(一般指类)中使用初始化列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <vector>

class Num
{
private:
std::vector<int> vv;
public:

Num(const std::initializer_list<int> &v)
{
for (auto a : v)
{
vv.push_back(a);
}
}

void PrintNum(void)
{
for (auto v : vv)
{
std::cout << v << " ";
}
std::cout << std::endl;
}
};

int main(int argc, char **argv)
{
Num n{1, 2, 3, 4};
n.PrintNum();

return 0;
}

实现方法,简单来说,就是加入 initializer_list 类型来实现构造函数,在新建对象时,就可以使用列表初始化的方式了。

四、一个特殊用法

在使用 python 的时候,有时候会这样操作

1
2
for i in [1,2,3]:
print(i)

看起来很简洁优雅,C++ 其实也有这种操作

1
2
3
4
5
6
7
8
9
#include <iostream>

int main(int argc, char **argv)
{
for(auto n : {1,2,3,4,5,6})
{
std::cout<<n<<std::endl;
}
}

参考原文
initializer_list、初始化列表、列表初始化

评论

:D 一言句子获取中...

加载中,最新评论有1分钟缓存...