跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

C++怎么使用contains_C++20查找优化教程【便捷】

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

相关文章