C++20中std::string::ends_with是constexpr且noexcept的成员函数,接受std::string_view、const char*或char,空后缀恒返回true,长度不足则返回false。

std::string::ends_with 在 C++20 中直接可用
只要编译器支持 C++20(如 GCC 10+、Clang 12+、MSVC 19.30+),且未禁用 std::string_view 相关特性,std::string::ends_with 就是成员函数,无需额外头文件( 已足够)。它返回 bool,语义清晰,比手写 substr + compare 更安全、更易读。
ends_with 接收的参数类型有三种,别传错
这个函数重载了三次,分别接受:std::string_view、const char*、单个 char。传 std::string 会触发隐式转换为 std::string_view,没问题;但若传 std::string& 或临时 std::string,仍走的是 string_view 构造路径,开销极小。常见错误是误以为能传 std::vector 或自定义字符串类——不行,必须是上述三种之一。
- ✅ 正确:
s.ends_with("txt")、s.ends_with(std::string_view{"log"})、s.ends_with('.') - ❌ 错误:
s.ends_with(std::string{"bak"})虽可编译(因隐式转 view),但不如直接写字面量;更糟的是s.ends_with(my_str.c_str())若my_str生命周期短于调用,会导致悬垂指针(因为const char*重载不复制内容)
空字符串和长度不足时的行为很明确
ends_with 对边界情况处理一致:空后缀(如 "" 或 std::string_view{})总是返回 true;如果原字符串长度小于后缀长度,直接返回 false,不会越界或抛异常。这比手动用 rfind 判断更省心。
- 例如:
std::string{"abc"}.ends_with("abcd")→false -
std::string{""}.ends_with("")→true -
std::string{"data"}.ends_with('a')→true(检查最后一个字符)
兼容性 fallback:C++17 及之前怎么模拟
如果项目还卡在 C++17,别硬升标准。可用 std::equal + 反向迭代器安全模拟,比 substr 更高效(避免内存分配):
template<typename s typename t>
bool ends_with(const S& s, const T& suffix) {
if (suffix.length() > s.length()) return false;
return std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
}
</typename>
注意:该模板对 std::string、std::string_view、C 风格字符串都适用,但要求 T 支持 .length() 和反向迭代器;若需支持纯 const char*,得额外偏特化或用 std::char_traits::length。
真正容易被忽略的是:C++20 的 ends_with 是 constexpr 且 noexcept,而自己写的 fallback 很难同时满足这两点——尤其当输入含非字面量 std::string_view 时,编译期求值就失效了。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











