initializer_list
是 C++11 中的一个特性,它允许你使用花括号 {}
中的值列表来初始化容器或数组。通常用于初始化标准库容器,比如 std::vector
、std::set
、std::map
以及数组
, 也可以用于包含容器成员的自定义类。
场景一:用初始化列表初始化容器
std::vector<int> arr = {1, 2, 3, 4, 5};
std::set<int> myset = {1, 2, 3, 4, 5, 2};
std::map<int, char> mymap = {{1, a}, {2, b}, {3, c}};
这种初始化方式使代码更简洁和可读,在背后使用了 initializer_list
的机制
场景二:直接使用初始化列表
#include <iostream>
#include <initializer_list>
int main()
{
std::initializer_list<int> numbers = {1, 2, 3, 4, 5};
for (const int& num : numbers)
{
std::cout << num << " ";
}
return 0;
}
可以像一般的数组一样使用initializer_list
,但这样没有什么太大的意义,如果想节省性能可直接用原始数组,如果想要方便操作可以用std::vector
, 这里要说明的是:
std::initializer_list
相比于std::vector
更为轻量级,它只存储了一个指向列表内存的指针和一个表示元素数量的整数变量,而std::vector还需要维护其插入、迭代、删除等等操作所需要的其他辅助资源。
主要应用场景:初始化一个类的容器成员
考虑一个简单的类MyClass
,它包含一个vector容器
成员。比较两种不同的构造函数,一种使用std::initializer_list
,另一种使用std::vector
作为参数:
#include <iostream>
#include <vector>
#include <initializer_list>
class MyClass
{
public:
// 构造函数使用 std::initializer_list
MyClass(std::initializer_list<int> values)
: numbers(values) {}
// 构造函数使用 std::vector 作为参数
MyClass(const std::vector<int>& values)
: numbers(values) {}
private:
std::vector<int> numbers;
};
int main()
{
// 使用 std::initializer_list 初始化 MyClass
MyClass obj1 = {1, 2, 3, 4, 5};
// 使用 std::vector 初始化 MyClass
std::vector<int> values = {1, 2, 3, 4, 5};
MyClass obj2(values);
return 0;
}
可以看到,使用initializer_list
的优点
- 方便。可以用初始化列表初始化我们自定义的类,这玩意儿在某些应用场景下是特别方便且代码可读性极高,各位慢慢探索。
- 比 std::vector 更轻量和高效。 当你使用
nitializer_lis
作为形参时,在值传递过程中,只包括一个指向初始化列表元素的指针和一个表示元素数量的整数。
注意一下,如果不显示提供initializer_list
作为形参的构造函数,是不能用初始化列表来初始化实例对象的。比如,你以为可以,但实际上不可以的这种情况:
class MyClass
{
public:
// 构造函数使用 std::vector 作为参数
MyClass(const std::vector<int>& values)
: numbers(values) {}
private:
std::vector<int> numbers;
};
int main()
{
MyClass obj1 = { 1, 2, 3, 4, 5 };
return 0;
}
但可以这样:MyClass obj1({1,2,3,4,5});
以上都针对容器而言,不包含容器的自定义类是可以直接用初始化列表的
#include <vector>
class MyClass
{
public:
MyClass(const int& a, const int& b)
: m_A(a), m_B(b) {}
private:
int m_A;
int m_B;
};
int main()
{
MyClass obj1 = {1, 2};
return 0;
}