resize(n)不传第二参数时新元素值初始化:内置类型为0/nullptr,类类型调用默认构造函数;传参时按拷贝或移动构造填充,不支持自定义初始化。

resize() 不传第二个参数时用什么值初始化新元素
当调用 vector::resize(n) 且不提供第二个参数时,新插入的元素会进行**值初始化(value-initialization)**:对内置类型(如 int、double、指针)填充为 0(或 nullptr),对类类型则调用其默认构造函数。
注意这不是“默认初始化”,也不是“零初始化”的简单等价——它依赖于类型的定义方式。例如:
std::vector<int> v1;
v1.resize(3); // v1 = {0, 0, 0}
std::vector<std::string> v2;
v2.resize(2); // v2[0] 和 v2[1] 都是空字符串(调用 string())
struct S { int x; };
std::vector<S> v3;
v3.resize(1); // v3[0].x == 0(S 被值初始化,成员 x 为 0)
resize(n, value) 中的 value 是拷贝还是移动
传入第二个参数时,resize(n, value) 会对每个新增位置执行 拷贝构造(C++11 及以后,若 value 是右值且类型支持移动,则可能触发移动构造;但实践中多数情况是拷贝)。
关键点在于:这个 value 是你提供的实参,它会被多次复制(或移动)进新位置,不是“复用同一个对象”。
立即学习“C++免费学习笔记(深入)”;
- 如果
value是临时对象(如resize(5, std::string("hello"))),编译器可能优化掉部分拷贝(RVO/NRVO 或移动语义) - 如果
value是左值(如std::string s = "hi"; v.resize(3, s);),则明确调用拷贝构造 - 对自定义类型,确保拷贝构造函数(或移动构造函数)是 public 且可用的,否则编译失败
想用非默认/非拷贝方式初始化(比如 placement new 或工厂函数)怎么办
resize() 本身不支持自定义初始化逻辑。它只做两件事:调整大小 + 用统一值填充。如果你需要每个新元素走不同构造路径(比如带参数构造、从池中分配、延迟初始化),就得绕过 resize()。
常见替代方案:
- 先
reserve()预留空间,再用emplace_back()逐个就地构造:v.reserve(n); for (int i = 0; i - 用循环配合
push_back()或emplace_back(),控制每次构造参数 - 若已知全部元素可统一构造但参数复杂,先构造一个临时对象,再传给
resize(n, temp)—— 注意这仍依赖拷贝/移动
没有“resize 并用 lambda 初始化”的标准接口。别试图重载或特化 resize,那是徒劳的。
bool vector resize 的陷阱:为什么 resize(5, true) 后可能全是 false
这是最容易踩的坑:std::vector<bool></bool> 是特化模板,内部以位为单位存储,resize() 行为在某些旧编译器或特定标准库实现中存在未定义或意外表现(尤其涉及引用代理和临时位操作)。
更稳妥的做法:
- 避免对
std::vector<bool></bool>依赖resize(n, value)的精确行为 - 改用
std::vector<char></char>或std::deque<bool></bool>替代(如果真需要布尔容器) - 或者 resize 后显式遍历赋值:
v.resize(5); std::fill(v.begin(), v.end(), true);
这个问题根源不在 resize 本身,而在 vector<bool></bool> 这个被广泛批评的特化设计上——它连 data() 都不提供,更别说可靠地支持所有泛型操作。








