应使用 empty() 判断字符串是否为空,因其语义清晰、常量时间、无副作用且可读性最强;避免 str == ""、size() == 0、c_str() == nullptr、str[0] == '\0' 等错误写法。

用 empty() 判断字符串是否为空最直接
在 C++ 中,std::string 的 empty() 成员函数专为判空设计,语义清晰、意图明确。它返回 bool,内部通常只是比较 size() == 0,但编译器优化后几乎无额外开销。
常见错误是写成 str == "" 或 str.length() == 0:前者触发临时对象构造和逐字符比较,后者虽安全但不如 empty() 直观;更隐蔽的问题是有人误用 str.c_str() == nullptr——c_str() 永远不返回空指针,哪怕字符串为空。
-
empty()是常量时间、无副作用、可读性最强的选择 - 不要用
size() == 0做逻辑判断——它可行但弱化了语义,且对某些自定义容器(如std::vector)可能有符号类型隐式转换风险(size_type是无符号) - 避免
str[0] == '\0':当字符串为空时,operator[]不检查边界,行为未定义
empty() 和 size() 在性能上没实际差别
从标准库实现角度看,现代 libstdc++、libc++ 和 MSVC STL 都把 empty() 实现为 return size() == 0; 或直接访问内部长度字段(如 _M_length == 0)。两者都是 O(1),且绝大多数编译器会内联并完全优化掉差异。
真正影响性能的不是这里,而是你是否在循环里反复调用——比如 for (int i = 0; i 比 for (int i = 0, n = s.size(); i 多一次函数调用(虽然仍极快),但这和 empty() 无关。
立即学习“C++免费学习笔记(深入)”;
- 别为了“省一个函数调用”而用
size() == 0替代empty() - 如果真在 hot path 里频繁判空,确保字符串本身是局部变量或已知不涉及小字符串优化(SSO)切换开销
- 注意:C++20 起
std::string_view同样提供empty(),行为一致,且无内存分配开销
空字符串和 null 字符串容易混淆
C++ 里没有“null string”概念(不像 Java 或 C#)。std::string 对象本身不能为 nullptr;所谓“空”仅指内容长度为 0。如果你看到 if (!ptr) 检查,那 ptr 是 std::string* 或 const char*,不是 std::string。
-
std::string s;→ 默认构造,s.empty()为true -
std::string* p = nullptr;→ 指针为空,必须先判空再解引用:if (p && p->empty()) -
const char* c = nullptr;→ 不能传给std::string(c),会崩溃;需先检查c是否非空
自定义字符串类或 C 风格字符串要区别对待
如果代码里混用了 C 风格字符串(const char*),empty() 就不存在了,得用 !c || *c == '\0'。而自己写的字符串类若没实现 empty(),就别硬套 STL 习惯。
另外,某些嵌入式或旧项目用 typedef char[32] str_t; 这类固定数组,此时“空”的定义取决于业务(全零?首字节零?),empty() 完全不适用,必须按约定检查。
- 统一用
std::string时,坚持用empty() - 对接 C API 返回的
const char*,优先用std::string_view(s)再调empty(),避免无谓拷贝 - 跨模块传递字符串时,明确约定“空值”是否允许为
nullptr,否则运行时崩得毫无征兆
真正该花时间想的,不是 empty() 快不快,而是你那个 if 分支里,是不是本该用 std::optional<:string> 来表达“不存在”的语义。










