std::basic_string::contains 是 C++23 新增的 bool 返回成员函数,语义清晰、避免隐式转换警告;仅支持 string_view、C 字符串或单字符参数,不支持搜索起始位置、大小写不敏感或正则匹配。

std::basic_string::contains 是 C++23 新增成员函数
它直接返回 bool,语义清晰:子串存在即为 true,不存在即为 false。相比老写法 str.find(sub) != std::string::npos,少写一长串判断逻辑,也避免了 size_type 与整数比较的隐式转换警告(尤其在启用 -Wsign-compare 时)。
替代 find 的写法要改三处细节
最常见错误是直接把 find 换成 contains 却忽略参数类型和重载差异:
-
contains只接受std::basic_string_view、C 风格字符串(const CharT*)或单字符(CharT),不接受std::string的右值引用或迭代器范围 - 传
std::string会触发隐式构造string_view,通常没问题;但若原string生命周期短于contains调用,可能引发悬垂视图(虽罕见,但需留意) - 不能像
find那样指定搜索起始位置——contains总是全局搜索,没有pos参数
编译器支持和降级兼容方案
截至 GCC 13、Clang 16、MSVC 19.35,默认仍不开启 C++23 模式。若项目暂不能升级标准,可用宏检测 + 内联封装:
#if __cpp_lib_string_contains >= 202011L
return str.contains("foo");
#else
return str.find("foo") != std::string::npos;
#endif
注意:__cpp_lib_string_contains 是库特性宏,比语言标准宏(如 __cpp_constexpr)更可靠;不要用 __cplusplus == 202302L 判断,因部分编译器延迟更新该宏。
性能和可读性取舍点
contains 和 find 底层实现几乎一致(都是调用相同的查找算法),性能无差异。但要注意:
- 若后续还需子串位置(比如提取匹配后内容),硬套
contains再调一次find就是重复搜索,应保留原find写法 - 在模板代码中,若
T是任意容器而非仅std::string,别假设它有contains——标准容器只有std::string和std::wstring等少数几个加了这个成员 - 第三方字符串类(如
absl::string_view或folly::fbstring)目前均未跟进该接口,跨库时仍得靠find
真正容易被忽略的是:contains 不区分大小写,也不支持正则,所有“模糊匹配”需求它都无能为力——这时候 find 至少还能配合 std::search 或 std::regex_search 延伸,而 contains 就只是个开关。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











