::fast_io::vector

English

1. 什么是 vector?

::fast_io::vector<T> 存储一串 T 类型的元素。 当你添加更多元素时,它会自动增长,且所有元素都连续存放在同一块内存中。

你可以把它想象成一个“会增长的数值列表”,始终保持紧密排列。

2. 创建 vector

你可以创建空 vector,也可以创建带初始大小的 vector:


#include <fast_io.h>
#include <fast_io_dsal/vector.h>

int main() {
    using namespace ::fast_io::iomnp;

    ::fast_io::vector<std::size_t> a;            // empty
    ::fast_io::vector<std::size_t> b(5zu);       // 5 default-initialized elements
    ::fast_io::vector<std::size_t> c(3zu, 42zu); // 3 copies of value 42

    println("b size = ", b.size());
    println("c[0] = ", c[0]);
}

3. 添加元素

添加元素最常见的方式是 push_back():


#include <fast_io.h>
#include <fast_io_dsal/vector.h>

int main() {
    using namespace ::fast_io::iomnp;

    ::fast_io::vector<std::size_t> v;

    v.push_back(10zu);
    v.push_back(20zu);
    v.push_back(30zu);

    println("Size: ", v.size()); // 3
}

当 vector 空间用尽时,它会自动分配更多内存。

4. 安全地访问元素

你可以用 front()、back() 或 operator[] 访问元素:


#include <fast_io.h>
#include <fast_io_dsal/vector.h>

int main() {
    using namespace ::fast_io::iomnp;

    ::fast_io::vector<std::size_t> v{1zu, 2zu, 3zu, 4zu};

    println("Front: ", v.front()); // 1
    println("Back: ",  v.back());  // 4
    println("Index 2: ", v[2]);    // 3
}

⚠️ 安全提示:如果你访问一个不存在的元素(例如在空 vector 上调用 v.front(),或使用越界索引),fast_io 会执行 边界检查。如果检查失败,程序会通过 __builtin_trap() 立刻停止。

安全用法


if(!v.is_empty()) {
    println("Front: ", v.front());
}

std::size_t i = 2zu;
if(i < v.size()) {
    println("v[2] = ", v[i]);
}

5. 遍历元素

首选:基于范围的 for 循环

这是遍历所有元素最简单的方式:


#include <fast_io.h>
#include <fast_io_dsal/vector.h>

int main() {
    using namespace ::fast_io::iomnp;

    ::fast_io::vector<std::size_t> v{10zu, 20zu, 30zu};

    for(std::size_t x : v) {
        println(x);
    }
}

替代方案:索引循环

当你需要位置时很有用:


for(std::size_t i{}, n{v.size()}; i != n; ++i) {
    println("Index ", i, ": ", v[i]);
}

进阶:迭代器

在第 3.1 节(字符串迭代器)中,我们介绍了迭代器的行为类似 指向容器内存的指针这一概念。::fast_io::vector<T> 使用与 ::fast_io::string 相同的迭代器模型。

这意味着:

示例:


#include <fast_io.h>
#include <fast_io_dsal/vector.h>

int main() {
    using namespace ::fast_io::iomnp;

    ::fast_io::vector<std::size_t> v{10zu, 20zu, 30zu};

    for(auto it = v.begin(), ed = v.end(); it != ed; ++it) {
        println(*it);
    }
}

迭代器算术

正如字符串一样,vector 的迭代器支持随机访问操作:


auto it = v.begin();        // first element
println(*(it + 1));         // move forward
println((it + 2)[0]);       // same as v[2]
println((it + 2)[-1]);      // move backward from a valid position

这些操作很快,但它们不做边界检查。

迭代器失效

任何导致 vector 增长的操作都可能重新分配其存储。 一旦发生这种情况,所有已有迭代器都会失效。


auto it2 = v.begin();
v.push_back(999zu);  // may reallocate

// ⚠️ it2 may now point to old memory
// println(*it2);   // undefined behavior

如果你需要在重新分配后保留位置,请保存索引而不是迭代器。

6. 删除元素

pop_back()

删除最后一个元素:


v.pop_back();

⚠️ 在空 vector 上调用 pop_back() 会让程序立刻停止。

7. 清空与释放内存

clear()

移除所有元素,但保留已分配的内存。 当你打算很快复用这个 vector 时很有用。


v.clear();
println(v.size()); // 0

clear_destroy()

移除所有元素,并把内存归还给分配器。 调用之后,vector 变成完全不占存储的空状态。


v.clear_destroy(); // memory returned to allocator
println(v.size()); // 0

当你用完 vector 并想释放它的内存时,使用 clear_destroy()。

要点