empty()是最安全的判空方式,语义清晰、性能最优且无未定义行为;它不依赖size计算,底层常数时间比较begin与end迭代器,避免了size()的调试开销、下标访问崩溃、类型转换陷阱及可读性差等问题。
直接调用 empty() 成员函数,返回 bool,语义清晰、性能最优,且不会引发越界或未定义行为。它不依赖 size 计算,底层通常只是比较 begin 和 end 迭代器是否相等,常数时间完成。
常见错误是用 size() == 0 替代——虽然结果一致,但某些调试构建下 size() 可能带额外检查开销;更危险的是有人写 v[0] == something 或 !v.data() 来“判断为空”,这在空 vector 下会崩溃或返回错误结果。
empty() 是 const 成员函数,可在 const vector 上安全调用front()、back() 或下标访问,哪怕只是想“看看有没有元素”if (v.empty()) return;,而不是靠循环条件隐式处理它们逻辑上等价,但各有隐患: v.size() > 0 多一次整数比较,无实质问题,但不如 empty() 直观;真正要警惕的是 v.begin() == v.end —— 它确实正确,但可读性差,且容易误写成 
v.begin() == v.begin() 或漏掉 const 正确性(比如对临时 vector 取 end() 后再比较)。
另外,size() 返回的是无符号类型 size_type,若与有符号数(如 int i = -1)比较,可能触发隐式转换导致意外结果,而 empty() 完全规避这类类型陷阱。
这是 C++ 中惯用且推荐的写法,简洁又明确表达意图:
if (v.empty()) {
std::cout << "vector is empty\n";
}
不需要写成 if (v.empty() == true) 或 if (!v.empty() == false),后者不仅冗余,还可能掩盖编译器对恒真/恒假条件的警告。
string、deque、list 等)都提供同名 empty() 接口,风格统一empty() 比依赖 size() 更泛化,因为并非所有符合 Container 概念的类型都要求实现 size()
std::span)没有 size(),但仍有 empty()
调用 empty() 只是查询状态,完全不改变 vector 内部任何数据。即使 vector 已经清空(比如调过 clear()),其 capacity() 通常仍保持不变——这意味着后续 push_back 可能无需重新分配内存。
如果你需要真正“归零”内存占用,得显式调用 v.clear(); v.shrink_to_fit();,但这是另一个问题了。别指望 empty() 做清理工作,它连一个字节都不会动。
最容易被忽略的一点:empty() 的返回值不能用于推导容器是否“刚构造”或“从未插入过”,因为 vector 可以通过 reserve 预分配空间后仍为空——此时 empty() 返回 true,但 capacity() 已大于 0。