
vector::assign 的作用是清空当前容器,再用新数据填充——它不是追加,也不是部分更新,而是彻底重置。调用后 size() 变为新数据长度,capacity() 可能收缩(取决于实现),原所有元素被析构,内存可能重新分配。
常见误用是把它当 insert 或 fill 用,结果意外丢掉原有数据。如果你只想改部分值,该用下标赋值或 std::copy;如果想保留容量并重填,assign 是最干净的选择。
最常遇到的两个重载:
v.assign(n, val):把容器设为 n 个重复的 val,适用于初始化同质数据,比如 v.assign(5, 42) 得到 {42,42,42,42,42}
v.assign(first, last):用迭代器范围 [first, last) 替换全部内容,支持其他容器、数组、initializer_list,比如 v.assign(arr, arr + 3) 或 v.assign({1,2,3})
注意:first 和 last 必须合法且构成有效范围,否则行为未定义;用 initializer_list 时,编译器需支持 C++11 以上。
立即学习“C++免费学习笔记(深入)”;
和 resize() 不同,assign 不保证保留原有容量。某些标准库实现(如 libstdc++)在 n 明显小于当前 capacity() 时会主动 shrink,但不强制。如果你对性能敏感(比如频繁 assign 小数据),可手动 v.clear(); v.shrink_to_fit(); 再 assign,或直接用 v = std::vector<t>(n, val)</t> 避免中间状态。
另一个坑:若 T 是非 trivial 类型,assign 会逐个调用析构和构造,开销不可忽略;对于 POD 类型,底层可能用 memmove 优化,但别依赖这个。
以下情况优先考虑别的做法:
v[i] = x 或 v.at(i) = x
v.insert(v.end(), ...) 或 v.emplace_back()
v.resize(n); std::fill(v.begin(), v.end(), val)
v = other_v 或 v.assign(other_v.begin(), other_v.end()),后者略显冗余assign 最适合“我确定要扔掉旧内容,用一套全新数据完全替代”的场景,比如解析配置后一次性加载一组参数,或帧间重置缓冲区。滥用它会导致不必要的析构/构造,也掩盖了真实意图。