
### C++ 标准库 `queue` 用法详解


#### **1. 基本概念**
- **头文件**：`<queue>`
- **命名空间**：`std`（通常配合 `using namespace std;` 或直接 `std::queue` 使用）
- **本质**：是一个**容器适配器（Container Adapter）**，通过封装底层容器（如 `deque`、`list`）实现**队列（FIFO，先进先出）**功能。
- **特点**：只能从队尾（Back）插入元素，从队头（Front）删除元素，不支持遍历和随机访问。


#### **2. 定义与初始化**
```cpp
#include <queue>
#include <deque>    // 底层容器（可选，默认是 deque）
#include <list>     // 也可以用 list 作为底层容器

// 定义方式：queue<数据类型, 底层容器类型> 队列名;
std::queue<int> q1;                     // 默认底层容器为 deque<int>
std::queue<int, std::deque<int>> q2;    // 显式使用 deque
std::queue<int, std::list<int>> q3;     // 使用 list 作为底层容器（支持双向删除，适合频繁头删的场景）

// 初始化：不能直接初始化（容器适配器不支持直接初始化列表），需通过 push 逐个插入
q1.push(1);
q1.push(2);
```


#### **3. 常用成员函数**

| 函数                | 描述                                                                 |
|---------------------|----------------------------------------------------------------------|
| **`push(value)`**   | 将元素 `value` 插入队尾（底层调用 `container::push_back(value)`）。 |
| **`pop()`**         | 删除队头元素（底层调用 `container::pop_front()`），不返回值。       |
| **`front()`**       | 返回队头元素的引用（若队列为空，调用会导致未定义行为）。            |
| **`back()`**        | 返回队尾元素的引用（若队列为空，调用会导致未定义行为）。            |
| **`empty()`**       | 若队列为空，返回 `true`，否则 `false`。                             |
| **`size()`**        | 返回队列中元素的个数（底层调用 `container::size()`）。               |


#### **4. 详细用法示例**

##### **（1）元素操作**
```cpp
std::queue<int> q;

// 插入元素（队尾）
q.push(10);   // 队列：[10]
q.push(20);   // 队列：[10, 20]

// 访问队头和队尾元素
int front_val = q.front();   // 10
int back_val = q.back();     // 20

// 删除队头元素
q.pop();       // 队列：[20]，此时 front() 返回 20

// 检查队列状态
bool is_empty = q.empty();   // false（队列非空）
size_t len = q.size();       // 1
```

##### **（2）遍历队列（注意：不建议直接遍历，需临时拷贝）**
由于 `queue` 不支持迭代器，若需遍历，需逐个弹出并处理（但会修改原队列），或复制到其他容器：
```cpp
std::queue<int> q;
q.push(1); q.push(2); q.push(3);

// 方法 1：弹出并打印（修改原队列）
while (!q.empty()) {
    std::cout << q.front() << " ";  // 1 2 3
    q.pop();
}

// 方法 2：复制到临时队列（不修改原队列，需使用相同底层容器）
std::queue<int> temp = q;  // C++11 支持拷贝构造函数
while (!temp.empty()) {
    std::cout << temp.front() << " ";  // 1 2 3
    temp.pop();
}
```

##### **（3）自定义数据类型**
```cpp
struct Person {
    std::string name;
    int age;
};

std::queue<Person> people;
people.push({"Alice", 20});
people.push({"Bob", 25});

Person first = people.front();  // 访问队头元素
```


#### **5. 底层容器要求**
`queue` 要求底层容器支持以下操作：
- `back()`：获取队尾元素（用于 `push` 和 `back()` 函数）。
- `front()`：获取队头元素（用于 `front()` 函数）。
- `push_back(value)`：在队尾插入元素（用于 `push()` 函数）。
- `pop_front()`：删除队头元素（用于 `pop()` 函数）。

**支持的底层容器**：
- **`deque`（默认）**：双端队列，效率均衡，适合大多数场景。
- **`list`**：双向链表，适合频繁头删（`pop_front`）和尾插（`push_back`），但随机访问效率低。
- **不支持 `vector`**：因为 `vector` 没有 `pop_front()` 函数（需手动 `erase(begin())`，效率 O(n)）。


#### **6. 应用场景**
1. **广度优先搜索（BFS）**：队列天然适合按层遍历图或树。
   ```cpp
   // BFS 示例
   std::queue<int> q;
   q.push(root);
   while (!q.empty()) {
       int node = q.front(); q.pop();
       // 处理当前节点
       for (auto neighbor : adj[node]) {
           q.push(neighbor);
       }
   }
   ```
2. **任务队列**：按顺序处理任务，如多线程中的任务调度（需配合线程安全机制）。
3. **缓存队列**：限制队列长度，先进先出淘汰旧元素。


#### **7. 注意事项**
1. **空队列操作风险**：
   - 调用 `front()`/`back()` 前必须用 `empty()` 检查，否则可能导致程序崩溃（未定义行为）。
   - `pop()` 对空队列调用是安全的（无操作），但逻辑上应避免。
2. **线程安全**：标准库 `queue` 非线程安全，多线程环境需自行加锁（如 `std::mutex`）。
3. **底层容器选择**：
   - 若需高效头删和尾插，选 `list`；否则用默认的 `deque` 即可。
4. **不支持的操作**：
   - 不支持直接获取队列容量（但可通过 `size()` 间接获取）。
   - 不支持迭代器、反向迭代器、随机访问等操作。


#### **8. 与其他容器适配器对比**
| 容器适配器 | 底层容器默认 | 访问特性         | 典型场景         |
|------------|--------------|------------------|------------------|
| `queue`    | `deque`      | FIFO，队头删、队尾插 | BFS、任务队列    |
| `stack`    | `deque`      | LIFO，栈顶操作   | 表达式求值、括号匹配 |
| `priority_queue` | `vector`     | 优先级队列（默认最大堆） | 事件调度、Dijkstra算法 |


#### **总结**
`queue` 是 C++ 中实现 FIFO 逻辑的便捷工具，通过封装底层容器简化了队列操作。使用时需注意空队列的检查，根据场景选择合适的底层容器，并结合实际需求（如线程安全）扩展功能。其核心优势在于接口简单，专注于队列的基本操作，适合算法和数据结构中的典型应用（如 BFS）。在C++中，`queue` 是标准模板库（STL）提供的一种容器适配器，它遵循先进先出（FIFO）的原则，就像排队一样，先进入队列的元素会先被移除。下面详细总结 `queue` 的用法。

### 1. 头文件包含
要使用 `queue`，需要包含 `<queue>` 头文件。
```cpp
#include <queue>
```

### 2. 定义与初始化
可以使用以下方式定义和初始化一个 `queue`：
```cpp
#include <iostream>
#include <queue>

int main() {
    // 定义一个存储整数的队列
    std::queue<int> q;

    return 0;
}
```
也可以使用其他容器（如 `deque` 或 `list`）作为底层容器来初始化 `queue`：
```cpp
#include <iostream>
#include <queue>
#include <list>

int main() {
    std::list<int> myList = {1, 2, 3};
    std::queue<int, std::list<int>> q(myList);

    return 0;
}
```

### 3. 常用成员函数

#### 3.1 `push()`
用于在队列的尾部插入一个元素。
```cpp
#include <iostream>
#include <queue>

int main() {
    std::queue<int> q;
    q.push(10);
    q.push(20);
    q.push(30);

    return 0;
}
```

#### 3.2 `pop()`
移除队列的头部元素。注意，该函数没有返回值，如果需要获取头部元素的值，需要先使用 `front()` 函数。
```cpp
#include <iostream>
#include <queue>

int main() {
    std::queue<int> q;
    q.push(10);
    q.push(20);
    q.push(30);

    q.pop(); // 移除头部元素 10

    return 0;
}
```

#### 3.3 `front()`
返回队列的头部元素的引用。
```cpp
#include <iostream>
#include <queue>

int main() {
    std::queue<int> q;
    q.push(10);
    q.push(20);
    q.push(30);

    std::cout << "Front element: " << q.front() << std::endl; // 输出 10

    return 0;
}
```

#### 3.4 `back()`
返回队列的尾部元素的引用。
```cpp
#include <iostream>
#include <queue>

int main() {
    std::queue<int> q;
    q.push(10);
    q.push(20);
    q.push(30);

    std::cout << "Back element: " << q.back() << std::endl; // 输出 30

    return 0;
}
```

#### 3.5 `empty()`
判断队列是否为空，如果为空则返回 `true`，否则返回 `false`。
```cpp
#include <iostream>
#include <queue>

int main() {
    std::queue<int> q;
    std::cout << "Is queue empty? " << (q.empty() ? "Yes" : "No") << std::endl; // 输出 Yes

    q.push(10);
    std::cout << "Is queue empty? " << (q.empty() ? "Yes" : "No") << std::endl; // 输出 No

    return 0;
}
```

#### 3.6 `size()`
返回队列中元素的数量。
```cpp
#include <iostream>
#include <queue>

int main() {
    std::queue<int> q;
    q.push(10);
    q.push(20);
    q.push(30);

    std::cout << "Queue size: " << q.size() << std::endl; // 输出 3

    return 0;
}
```

### 4. 示例代码
下面是一个完整的示例，展示了 `queue` 的基本用法：
```cpp
#include <iostream>
#include <queue>

int main() {
    std::queue<int> q;

    // 插入元素
    q.push(1);
    q.push(2);
    q.push(3);

    // 输出队列元素
    while (!q.empty()) {
        std::cout << q.front() << " ";
        q.pop();
    }
    std::cout << std::endl;

    return 0;
}
```
这个示例首先创建了一个整数队列，然后向队列中插入三个元素，接着使用 `while` 循环遍历队列，输出队列中的元素并依次移除，直到队列为空。

通过以上的介绍，你可以掌握 C++ 中 `queue` 标准库的基本用法。