命名空间
变体
操作

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

来自 cppreference.cn
< cpp‎ | string‎ | basic string
 
 
 
std::basic_string
 
int compare( const basic_string& str ) const;
(1) (noexcept since C++11)
(constexpr since C++20)
int compare( size_type pos1, size_type count1,
             const basic_string& str ) const;
(2) (constexpr since C++20)
(3)
int compare( size_type pos1, size_type count1,

             const basic_string& str,

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

             const basic_string& str,

             size_type pos2, size_type count2 = npos ) const;
(since C++14)
(constexpr since C++20)
int compare( const CharT* s ) const;
(4) (constexpr since C++20)
int compare( size_type pos1, size_type count1,
             const CharT* s ) const;
(5) (constexpr since C++20)
int compare( size_type pos1, size_type count1,
             const CharT* s, size_type count2 ) const;
(6) (constexpr since C++20)
template< class StringViewLike >
int compare( const StringViewLike& t ) const noexcept(/* see below */);
(7) (since C++17)
(constexpr since C++20)
template< class StringViewLike >

int compare( size_type pos1, size_type count1,

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

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

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

比较两个字符序列。

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 时参与重载决议。

将由 count1 个字符组成的、起始于 data1 的字符序列与由 count2 个字符组成的、起始于 data2 的字符序列按如下方式比较

  • 首先,计算要比较的字符数,如同 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] 参见

(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(removed in C++20)(C++20)
按字典序比较两个字符串
(函数模板) [编辑]
返回子字符串
(公共成员函数) [编辑]
定义字符串的字典序比较和哈希
(类模板) [编辑]
根据当前区域设置比较两个字符串
(函数) [编辑]
如果一个范围在字典序上小于另一个范围,则返回 true
(函数模板) [编辑]
比较两个视图
(std::basic_string_view<CharT,Traits> 的公共成员函数) [编辑]