命名空间
变体
操作

std::basic_string<CharT,Traits,Allocator>::compare

来自 cppreference.com
< cpp‎ | string‎ | basic string
 
 
 
std::basic_string
成员函数
元素访问
迭代器
容量
修饰符
搜索
操作
basic_string::compare
常量
非成员函数
I/O
比较
(直到 C++20)(直到 C++20)(直到 C++20)(直到 C++20)(直到 C++20)(C++20)
数值转换
(C++11)(C++11)(C++11)
(C++11)(C++11)
(C++11)(C++11)(C++11)
(C++11)
(C++11)
字面量
辅助类
推导指南 (C++17)

 
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,

             size_type pos2, size_type count2 ) const;
(直到 C++14)
int compare( size_type pos1, size_type count1,

             const basic_string& str,

             size_type pos2, size_type count2 = npos ) const;
(自 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,

             const StringViewLike& t ) const;
(8) (自 C++17 起)
(自 C++20 起为 constexpr)
template< class StringViewLike >

int compare( size_type pos1, size_type count1,
             const StringViewLike& t,

             size_type pos2, size_type count2 = npos) const;
(9) (自 C++17 起)
(自 C++20 起为 constexpr)

比较两个字符序列。

1) 将此字符串与 str 进行比较。
2) 将此字符串的 [pos1pos1 + count1) 子字符串与 str 进行比较。
  • 如果 count1 > size() - pos1,则子字符串为 [pos1size())
3) 将此字符串的 [pos1pos1 + count1) 子字符串与 str[pos2pos2 + count2) 子字符串进行比较。
  • 如果 count1 > size() - pos1,则第一个子字符串为 [pos1size())
  • 如果 count2 > str.size() - pos2,则第二个子字符串为 [pos2str.size())
4) 将此字符串与从 s 指向的字符开始的以空字符结尾的字符序列进行比较,长度为 Traits::length(s)
5) 将此字符串的 [pos1pos1 + count1) 子字符串与从 s 指向的字符开始的以空字符结尾的字符序列进行比较,长度为 Traits::length(s)
  • 如果 count1 > size() - pos1,则子字符串为 [pos1size())
6) 将此字符串的 [pos1pos1 + count1) 子字符串与范围 [ss + count2) 中的字符进行比较。范围 [ss + count2) 中的字符可能包含空字符。
  • 如果 count1 > size() - pos1,则子字符串为 [pos1size())
7-9) 隐式地将 t 转换为字符串视图 sv,就好像使用 std::basic_string_view<CharT, Traits> sv = t; 一样,然后
7) 将此字符串与 sv 进行比较;
8) 将此字符串的 [pos1pos1 + count1) 子字符串与 sv 进行比较,就好像使用 std::basic_string_view<CharT, Traits>(*this).substr(pos1, count1).compare(sv) 一样。
9) 将此字符串的子字符串 [pos1pos1 + count1)sv 的子字符串 [pos2pos2 + 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>>
truestd::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] 异常

采用名为 pos1pos2 的参数的重载,如果参数超出范围,则抛出 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)
词典顺序比较两个字符串
(函数模板) [edit]
返回子字符串
(公有成员函数) [edit]
定义字符串的词典顺序比较和哈希
(类模板) [edit]
根据当前区域设置比较两个字符串
(函数) [edit]
如果一个范围在词典顺序上小于另一个范围,则返回 true
(函数模板) [edit]
比较两个视图
(std::basic_string_view<CharT,Traits> 的公有成员函数) [edit]