assign会清空原vector再赋新值,非追加;常用形式为v.assign(n,val)或v.assign(first,last),分别用n个val或迭代器范围赋值。

assign 会清空原 vector 再赋新值,不是追加
assign 的行为和 push_back 或 insert 完全不同:它先销毁原容器所有元素,再用新数据重建。如果你本意是“在末尾加几个数”,误用 assign 会导致已有数据全部丢失。
常见错误现象:v = {1,2,3}; v.assign({4,5}); 后 v 变成 {4,5},不是 {1,2,3,4,5}。
- 适用场景:初始化、重置、批量替换整段内容
- 不适用场景:日志累积、循环中逐步填充、拼接多个数据块
- 若需追加,请改用
insert(v.end(), ...)或insert(v.end(), range.begin(), range.end())
assign 的两种常用调用形式及参数含义
最常遇到的是两个重载版本,参数语义容易混淆:
-
v.assign(n, val):用n个重复的val赋值(n是size_type,不能是负数,否则触发未定义行为) -
v.assign(first, last):用迭代器范围[first, last)赋值,支持数组、其他容器、initializer_list
示例:
v.assign(3, 99); // v 变为 {99,99,99}
v.assign({1,2,3,4}); // v 变为 {1,2,3,4}(initializer_list 构造)
v.assign(arr, arr + 5); // arr 是 int[5],合法
注意:first 和 last 必须满足 first ,否则行为未定义 —— 这在指针运算或手动计算迭代器时容易出错。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
assign 和直接赋值 operator= 的性能与语义差异
对 std::vector 来说,v.assign(...) 和 v = {...} 在多数情况下效果一致,但底层动作不同:
-
v = {1,2,3}走的是 move-assignment(如果右值)或 copy-assignment;可能复用原有内存,也可能重新分配 -
v.assign({1,2,3})总是先 clear() 再 construct,等价于v.clear(); v.insert(v.end(), ...)的组合效果 - 性能上:当目标容量足够大时,
assign可能比=多一次析构+构造开销;但若原容器很大,assign避免了旧元素的逐个析构(直接覆盖),反而更快
实际建议:优先用 = 写 initializer_list 赋值(简洁安全);只有需要明确“用 n 个相同值重填”或“从某迭代器范围重填”时,才显式调用 assign。
assign 在 C++11 之后对 initializer_list 的支持细节
std::vector::assign 在 C++11 引入了接受 std::initializer_list 的重载,但要注意它和构造函数的重载解析规则:
-
v.assign({1,2,3})正确,调用assign(std::initializer_list<t>)</t> -
v.assign(3, 5)正确,调用assign(size_type, const T&) - 但
v.assign({3, 5})不会变成“3 个 5”,而是变成{3,5}—— 因为{3,5}被当作initializer_list,不是两个独立参数
这个点容易误判:看到 assign(a,b) 就以为是“数量+值”,结果传 {a,b} 却得到完全不同的结果。编译器不会报错,但逻辑已偏离预期。
真正要小心的是那个花括号——它决定走哪条重载路径,而这条路径和你直觉想的未必一致。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










