c++oding="utf-8" ?>
首选 empty() 判断 std::vector 是否为空,因其 o(1) 时间复杂度、语义清晰、无副作用且兼容所有标准容器;避免 size() == 0(可读性差、泛型不安全)和 front()/[0](未定义行为)。

用 empty() 是最安全直接的方式
判断 std::vector 是否为空,首选 empty() 成员函数。它不涉及任何迭代器操作或下标访问,时间复杂度 O(1),且语义清晰、无副作用。
-
empty()返回bool,true表示容器无元素,false表示至少有一个元素 - 不要用
size() == 0替代——虽然多数实现下等价,但empty()更明确表达意图,且某些容器(如 list)在 C++11 前size()可能非 O(1),而empty()始终是常数时间 - 绝对避免用
vec[0]或vec.front()判断——未检查空状态就访问会触发未定义行为,程序可能崩溃或静默出错
为什么不能用 size() == 0 作为默认习惯
size() 在 std::vector 中确实是 O(1),但它传递的是“数量”信息,而非“是否为空”的逻辑意图。这在代码可读性和维护性上埋下隐患。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 当后续把
vector换成其他容器(比如自定义容器或未来可能的std::span)时,size()的性能保证不一定成立,而empty()是所有标准容器的统一接口 - 静态分析工具(如 clang-tidy)会警告
size() == 0这类写法,推荐改用empty() - 在模板代码中泛化处理容器时,依赖
empty()才能兼容所有标准容器;size()对某些类型(如std::array)虽可用,但语义不统一
常见误判场景:迭代器和范围 for 前忘记检查
很多 bug 不是出在判断本身,而是判断后没同步约束后续操作的边界。
- 写
if (!vec.empty()) { auto it = vec.begin(); ... }是安全的;但若漏掉empty()检查,直接用vec.begin()配合vec.end()做循环,在空容器下虽不崩溃(begin() == end()合法),但容易掩盖逻辑疏漏 - 范围 for 循环(
for (auto& x : vec))本身对空容器安全,无需前置检查;但如果你在里面取了vec[0]或调用了front(),就必须单独 guard - 注意:
vec.front()和vec.back()在空容器上调用是未定义行为,哪怕你刚调过vec.size() == 0,也不能跳过empty()检查
调试时看到 vector::_M_impl._M_finish == vector::_M_impl._M_start 意味着什么
这是 libstdc++(GCC 默认 STL)在调试模式下打印的内部指针状态,直观反映空容器结构:起始和结束指针相等。
- 这不是你需要主动读取或比较的字段,仅作调试参考;正式代码中永远通过
empty()判断 - 不同 STL 实现(MSVC 的
std::vector、libc++)内部布局不同,直接访问私有成员不仅不可移植,而且在不同编译器/标准库版本下极易失效 - 如果在 debugger 里看到这个状态,可以快速确认容器确实为空,但上线代码绝不能依赖它
实际写法就一句:if (vec.empty()) { /<em> 处理空情况 </em>/ }。别绕,别猜,别碰内部指针。空容器不是边缘情况,是常态,每次访问前多一次 empty() 检查,比修复 core dump 省十倍力气。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










