《C++ Primer 第五版》 initializer_list

1️⃣ initializer_list 是什么?

在 C++11 里引入了 统一初始化语法

cpp 复制代码
int x{10};
vector<int> v{1,2,3,4};

这种用 {} 花括号的写法,底层就是靠 std::initializer_list 来支持的。

一句话理解
initializer_list<T> 就是一个 只读的轻量容器 ,里面保存了 {} 花括号里的那批常量元素。


2️⃣ 它的内部结构

std::initializer_list<T> 其实就是:

  • 一个指向常量数组的指针

  • 一个大小 size

所以它很轻量,拷贝、赋值都只是复制指针和大小,并不会真正复制所有元素。

⚠️ 元素是 只读 的,不能修改。


3️⃣ 典型用法

📌(1)作为容器初始化工具

cpp 复制代码
#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<int> v = {1, 2, 3, 4, 5}; // 内部调用 initializer_list 构造函数

    for (int x : v) cout << x << " ";
    return 0;
}

📌(2)作为函数参数

cpp 复制代码
#include <initializer_list>
#include <iostream>
using namespace std;

int sum(initializer_list<int> lst) {
    int total = 0;
    for (auto x : lst) total += x;
    return total;
}

int main() {
    cout << sum({1, 2, 3, 4}) << endl;  // 输出 10
}

这种写法非常优雅,不用传数组,也不用写循环。


📌(3)手工使用 initializer_list

cpp 复制代码
#include <iostream>
#include <initializer_list>
using namespace std;

int main() {
    initializer_list<int> lst{10, 20, 30};

    cout << "size = " << lst.size() << endl;
    cout << "first = " << *lst.begin() << endl;

    for (auto val : lst) cout << val << " ";
}

输出:

复制代码

size = 3 first = 10 10 20 30


4️⃣ 常见注意点

  1. 元素只读

    cpp 复制代码
    for (auto &x : lst) x = 100; // ❌ 错误,不能修改
  2. 生命周期

    • initializer_list 内部指向的是编译器生成的临时数组。

    • 所以不能返回一个局部 initializer_list 引用。

  3. 效率

    • 拷贝和赋值非常快,因为它只是浅拷贝。

5️⃣ 总结口诀

  • initializer_list<T> = {} 花括号背后的秘密。

  • 常用在 容器初始化函数参数传递

  • 本质:指针 + 大小,只读轻量容器

  • 优点:让 C++ 初始化和调用看起来更简洁,像脚本语言。


一句比喻:
initializer_list 就像 一次性快餐盒

  • 花括号 {} 放进什么,它就原封不动地打包。

  • 你可以拿来吃(遍历),但不能往里面加菜(只读)。

  • 盒子本身很轻,拷来拷去都没问题。