std::basic_string<CharT,Traits,Allocator>::compare
来自 cppreference.com
< cpp | string | basic string
int compare( const basic_string& str ) const; |
(1) | (自 C++11 起为 noexcept) (自 C++20 起为 constexpr) |
int compare( size_type pos1, size_type count1, const basic_string& str ) const; |
(2) | (自 C++20 起为 constexpr) |
(3) | ||
int compare( size_type pos1, size_type count1, const basic_string& str, |
(直到 C++14) | |
int compare( size_type pos1, size_type count1, const basic_string& str, |
(自 C++14 起) (自 C++20 起为 constexpr) |
|
int compare( const CharT* s ) const; |
(4) | (自 C++20 起为 constexpr) |
int compare( size_type pos1, size_type count1, const CharT* s ) const; |
(5) | (自 C++20 起为 constexpr) |
int compare( size_type pos1, size_type count1, const CharT* s, size_type count2 ) const; |
(6) | (自 C++20 起为 constexpr) |
template< class StringViewLike > int compare( const StringViewLike& t ) const noexcept(/* see below */); |
(7) | (自 C++17 起) (自 C++20 起为 constexpr) |
template< class StringViewLike > int compare( size_type pos1, size_type count1, |
(8) | (自 C++17 起) (自 C++20 起为 constexpr) |
template< class StringViewLike > int compare( size_type pos1, size_type count1, |
(9) | (自 C++17 起) (自 C++20 起为 constexpr) |
比较两个字符序列。
1) 将此字符串与 str 进行比较。
2) 将此字符串的
[
pos1,
pos1 + count1)
子字符串与 str 进行比较。- 如果 count1 > size() - pos1,则子字符串为
[
pos1,
size())
。
3) 将此字符串的
[
pos1,
pos1 + count1)
子字符串与 str 的 [
pos2,
pos2 + count2)
子字符串进行比较。- 如果 count1 > size() - pos1,则第一个子字符串为
[
pos1,
size())
。 - 如果 count2 > str.size() - pos2,则第二个子字符串为
[
pos2,
str.size())
。
4) 将此字符串与从 s 指向的字符开始的以空字符结尾的字符序列进行比较,长度为 Traits::length(s)。
5) 将此字符串的
[
pos1,
pos1 + count1)
子字符串与从 s 指向的字符开始的以空字符结尾的字符序列进行比较,长度为 Traits::length(s)。- 如果 count1 > size() - pos1,则子字符串为
[
pos1,
size())
。
6) 将此字符串的
[
pos1,
pos1 + count1)
子字符串与范围 [
s,
s + count2)
中的字符进行比较。范围 [
s,
s + count2)
中的字符可能包含空字符。- 如果 count1 > size() - pos1,则子字符串为
[
pos1,
size())
。
7) 将此字符串与 sv 进行比较;
8) 将此字符串的
[
pos1,
pos1 + count1)
子字符串与 sv 进行比较,就好像使用 std::basic_string_view<CharT, Traits>(*this).substr(pos1, count1).compare(sv) 一样。9) 将此字符串的子字符串
.substr(pos1, count1).compare(sv.substr(pos2, count2)) 一样。
[
pos1,
pos1 + count1)
与 sv 的子字符串 [
pos2,
pos2 + count2)
进行比较,如同使用 std::basic_string_view<CharT, Traits>(*this).substr(pos1, count1).compare(sv.substr(pos2, count2)) 一样。
这些重载只有在 std::is_convertible_v<const StringViewLike&,
std::basic_string_view<CharT, Traits>> 为 true 且 std::is_convertible_v<const StringViewLike&, const CharT*> 为 false 时参与重载解析。
std::basic_string_view<CharT, Traits>> 为 true 且 std::is_convertible_v<const StringViewLike&, const CharT*> 为 false 时参与重载解析。
由从 data1 开始的 count1 个字符组成的字符序列与由从 data2 开始的 count2 个字符组成的字符序列进行比较,如下所示
- 首先,计算要比较的字符数量,如同使用 size_type rlen = std::min(count1, count2) 一样。
- 然后,通过调用 Traits::compare(data1, data2, rlen) 来比较序列。对于标准字符串,此函数执行逐字符的词典比较。如果结果为零(到目前为止字符序列相等),那么它们的尺寸将按如下方式进行比较
条件 | 结果 | 返回值 | |
---|---|---|---|
Traits::compare(data1, data2, rlen) < 0
|
data1 小于 data2 | <0 | |
Traits::compare(data1, data2, rlen) == 0
|
size1 < size2 | data1 小于 data2 | <0 |
size1 == size2 | data1 等于 data2 | 0 | |
size1 > size2 | data1 大于 data2 | >0 | |
Traits::compare(data1, data2, rlen) > 0
|
data1 大于 data2 | >0 |
内容 |
[edit] 参数
str | - | 要比较的另一个字符串 |
s | - | 要比较的字符字符串的指针 |
count1 | - | 要比较的此字符串的字符数量 |
pos1 | - | 要比较的此字符串中第一个字符的位置 |
count2 | - | 要比较的给定字符串的字符数量 |
pos2 | - | 要比较的给定字符串中第一个字符的位置 |
t | - | 要比较的对象(可转换为 std::basic_string_view) |
[edit] 返回值
- 如果 *this 在词典顺序中出现在参数指定的字符序列之前,则为负值。
- 如果两个字符序列比较相等,则为零。
- 如果 *this 在词典顺序中出现在参数指定的字符序列之后,则为正值。
[edit] 异常
采用名为 pos1 或 pos2 的参数的重载,如果参数超出范围,则抛出 std::out_of_range。
7)
noexcept 规范:
noexcept(std::is_nothrow_convertible_v<const T&, std::basic_string_view<CharT, Traits>>)
8,9) 抛出转换为 std::basic_string_view 期间抛出的任何异常。
如果由于任何原因抛出异常,则此函数不会产生任何影响(强异常安全性保证)。
[edit] 可能的实现
重载 (1) |
---|
template<class CharT, class Traits, class Alloc> int std::basic_string<CharT, Traits, Alloc>::compare (const std::basic_string& s) const noexcept { size_type lhs_sz = size(); size_type rhs_sz = s.size(); int result = traits_type::compare(data(), s.data(), std::min(lhs_sz, rhs_sz)); if (result != 0) return result; if (lhs_sz < rhs_sz) return -1; if (lhs_sz > rhs_sz) return 1; return 0; } |
[edit] 备注
对于不需要三路比较的情况,std::basic_string 提供了通常的 关系运算符(<
、<=
、==
、>
等)。
默认情况下(使用默认的 std::char_traits),此函数不区分区域设置。有关区分区域设置的三路字符串比较,请参见 std::collate::compare。
[edit] 示例
运行此代码
#include <cassert> #include <iomanip> #include <iostream> #include <string> #include <string_view> void print_compare_result(std::string_view str1, std::string_view str2, int compare_result) { if (compare_result < 0) std::cout << std::quoted(str1) << " comes before " << std::quoted(str2) << ".\n"; else if (compare_result > 0) std::cout << std::quoted(str2) << " comes before " << std::quoted(str1) << ".\n"; else std::cout << std::quoted(str1) << " and " << std::quoted(str2) << " are the same.\n"; } int main() { std::string batman{"Batman"}; std::string superman{"Superman"}; int compare_result{0}; // 1) Compare with other string compare_result = batman.compare(superman); std::cout << "1) "; print_compare_result("Batman", "Superman", compare_result); // 2) Compare substring with other string compare_result = batman.compare(3, 3, superman); std::cout << "2) "; print_compare_result("man", "Superman", compare_result); // 3) Compare substring with other substring compare_result = batman.compare(3, 3, superman, 5, 3); std::cout << "3) "; print_compare_result("man", "man", compare_result); // Compare substring with other substring // defaulting to end of other string assert(compare_result == batman.compare(3, 3, superman, 5)); // 4) Compare with char pointer compare_result = batman.compare("Superman"); std::cout << "4) "; print_compare_result("Batman", "Superman", compare_result); // 5) Compare substring with char pointer compare_result = batman.compare(3, 3, "Superman"); std::cout << "5) "; print_compare_result("man", "Superman", compare_result); // 6) Compare substring with char pointer substring compare_result = batman.compare(0, 3, "Superman", 5); std::cout << "6) "; print_compare_result("Bat", "Super", compare_result); }
输出
1) "Batman" comes before "Superman". 2) "Superman" comes before "man". 3) "man" and "man" are the same. 4) "Batman" comes before "Superman". 5) "Superman" comes before "man". 6) "Bat" comes before "Super".
[edit] 缺陷报告
以下行为更改缺陷报告已追溯应用于以前发布的 C++ 标准。
DR | 应用于 | 发布的行为 | 正确行为 |
---|---|---|---|
LWG 5 | C++98 | 重载 (6) 的参数 count2 具有默认参数 npos |
删除了默认参数, 拆分为重载 (5) 和 (6) |
LWG 847 | C++98 | 没有异常安全性保证 | 添加了强异常安全性保证 |
LWG 2946 | C++17 | 重载 (7) 在某些情况下会导致歧义 | 通过将其设为模板来避免 |
P1148R0 | C++17 | 重载 (7) 的 noexcept 意外地 因 LWG2946 的解决而被删除 |
恢复 |
[edit] 参见
(已在 C++20 中移除)(已在 C++20 中移除)(已在 C++20 中移除)(已在 C++20 中移除)(已在 C++20 中移除)(C++20) |
词典顺序比较两个字符串 (函数模板) |
返回子字符串 (公有成员函数) | |
定义字符串的词典顺序比较和哈希 (类模板) | |
根据当前区域设置比较两个字符串 (函数) | |
如果一个范围在词典顺序上小于另一个范围,则返回 true (函数模板) | |
比较两个视图 ( std::basic_string_view<CharT,Traits> 的公有成员函数) |