resize() 不传第二个参数时用元素类型的默认构造值填充:内置类型为0或0.0,类类型调用默认构造函数。

resize() 不传第二个参数时用什么值填充
vector::resize() 调用时不传第二个参数,会默认使用元素类型的默认构造值:对内置类型(如 int、double)是零初始化(0、0.0),对类类型是调用其默认构造函数。
注意这不是“未定义值”或“栈上随机值”——C++ 标准明确要求默认初始化(default-initialization),而内置类型在 default-initialization 下若为局部变量则值不确定,但 resize() 内部实际执行的是 value-initialization(等价于 T()),所以结果总是确定的零值或默认构造对象。
-
vector→v; v.resize(3); v变成{0, 0, 0} -
vector→ 两个空字符串v; v.resize(2); { "", "" } -
vector→> v; v.resize(1); { {0, 0} }(pair的默认构造会 value-initialize 成员)
resize() 第二个参数指定填充值的用法
直接传入一个值作为第二参数,所有新增元素都会被拷贝构造(或移动构造)该值:
vectorv = {1, 2}; v.resize(5, 99); // → {1, 2, 99, 99, 99}
这个值必须能隐式转换为 vector 元素类型,且参与的是拷贝/移动构造,不是赋值。因此对不可拷贝类型(如 unique_ptr)需确保传入的是可移动的右值。
立即学习“C++免费学习笔记(深入)”;
- 支持自定义类型:
MyClass x; v.resize(3, x);要求MyClass有可访问的拷贝构造函数 - 避免临时对象生命周期问题:
v.resize(3, MyClass{42});安全,因为MyClass{42}是纯右值,会被移动构造(C++11 起) - 不推荐用指针或引用类型做填充值,容易引发悬空或意外共享
assign() 和 resize() 填充行为的区别
assign() 是完全替换内容,而 resize() 只影响 size,不改变已有元素;但两者都支持指定填充值,语义不同:
-
v.assign(4, 7);→ 无论原v是什么,变成{7,7,7,7} -
v.resize(4, 7);→ 若原v有 5 个元素,只截断到 4,不填充;若原 size=2,则后两个填7
也就是说,assign() 更接近“重置并填充”,resize() 是“伸缩并按需填充”。当需要确保容器长度且统一初始化新位置时,resize(n, val) 更精准;若想彻底清空再填,assign() 或先 clear() 再 resize() 都可以,但后者多一次析构+构造开销。
初始化 vector 时就指定大小和填充值的写法
构造时直接指定大小和填充值,比先默认构造再 resize() 更高效(避免默认构造 + 后续赋值/构造):
vectorv(5, 42); // {42,42,42,42,42} vector w(3, "hi"); // {"hi","hi","hi"}
这调用的是 vector(size_type n, const T& value) 构造函数,内部直接批量构造,不经过默认构造再填充的过程。对于大容量或非 trivial 类型(如含资源管理的类),性能差异明显。
注意:不能写成 vector——这是 initializer_list 构造,结果是 {5, 42},不是 5 个 42。
真正容易被忽略的是:resize() 的填充值参数是 const T&,对 move-only 类型(如 unique_ptr)必须显式用 std::move 传入右值,否则编译失败;而构造函数版本同样适用这一规则。










