std::string::contains 在 C++20 中并不存在;标准库中可用的是 std::string::find()、std::string_view::find() 和 std::ranges::search(),推荐使用 find() != npos 判断子串存在性。
std::string::contains 在 C++20 中根本不存在
别被名字骗了:
不是 C++20 标准的一部分。你搜到的“
教程”大概率是误传、实验性扩展(如某些 lib
c++
的私有补丁),或把
/
包装成
的 DIY 写法。
标准库真正可用的是:
—— 返回
,查不到时返回
—— 更轻量,适合只读子串查找
+
—— C++20 范围算法,但查子串需配合
,不直接等价于 “包含字符串”
替代
的三种安全写法(C++20 可用)
想判断一个
是否包含某子串,最常用且无歧义的方式仍是
。C++20 没新增语义,但可借助
提升效率和表达力:
对字面量或只读子串:优先用
调用
,避免临时
构造
封装成内联函数(非成员)比依赖不存在的成员函数更可靠:
这个函数在 C++17 也能用,C++20 下无额外开销;别写成
—— 编译不过。
立即学习
“
C++免费学习笔记(深入)
”;
为什么不用
查子串?
只能找单个字符(或满足一元谓词的元素),不是为子串匹配设计的。试图这样写会出错:
C知道
CSDN推出的一款AI技术问答工具
下载
真要用范围算法查子串,得上
,但它返回迭代器对,写起来更啰嗦,性能也不优于
:
除非你在处理自定义容器或需要统一使用范围接口,否则没必要绕路。
容易踩的坑:
类型和比较写法
是
类型(通常是
),和
或
混用会触发隐式转换警告甚至逻辑错误:
❌
——
转成大正数,永远为真
✅
—— 唯一安全写法
⚠️
同样错,因为
是无符号类型,
恒成立
现代编辑器(如 clangd、msvc IntelliSense)通常会标出这类比较问题,但靠工具不如养成写
的肌肉记忆。
子串查找这事没捷径,
是经过三十年验证的接口。所谓“优化教程”,往往优化的是认知偏差——先确认标准里有没有,再动手封装。
std::string::containscontainsstd::ranges::findstd::string_view::findcontainsstd::string::find()size_tstd::string::nposstd::string_view::find()std::ranges::find()std::ranges::end()std::searchcontainsstd::stringfind() != nposstd::string_viewstd::string_viewfind()std::stringinline bool contains(const std::string& s, const std::string_view& substr) {
return s.find(substr) != std::string::npos;
}s.contains(substr)std::ranges::findstd::ranges::find// ❌ 错误!这是在找第一个等于 "abc" 的 char* 元素,不是子串
std::ranges::find(str, "abc"); // 类型不匹配,编译失败std::ranges::searchfind()auto res = std::ranges::search(str, substr);
bool found = res.begin() != res.end(); // 多此一举nposstd::string::npossize_tunsigned long-1intif (s.find("x") != -1)-1if (s.find("x") != std::string::npos)auto pos = s.find("x"); if (pos >= 0)pos>= 0!= nposfind