Namespaces
Variants

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

From cppreference.net
std::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,

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 ( /* 见下文 */ ) ;
(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) 将此字符串的 [ 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-9) 隐式转换 t 为字符串视图 sv ,如同通过 std:: basic_string_view < CharT, Traits > sv = t ; 实现,随后
7) 将此字符串与 sv 进行比较;
8) 将此字符串的 [ pos1 , pos1 + count1 ) 子串与 sv 进行比较,操作方式类似于 std:: basic_string_view < CharT, Traits > ( * this ) . substr ( pos1, count1 ) . compare ( sv )
9) 将此字符串的 [ 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

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

目录

参数

str - 要比较的其他字符串
s - 指向要比较的字符字符串的指针
count1 - 要比较的此字符串的字符数
pos1 - 此字符串中要比较的第一个字符的位置
count2 - 要比较的给定字符串的字符数
pos2 - 给定字符串中要比较的第一个字符的位置
t - 要比较的对象(可转换为 std::basic_string_view

返回值

  • 负值,若 * this 按字典序出现在参数指定的字符序列之前。
  • 零,若两个字符序列比较结果等价。
  • 正值,若 * this 按字典序出现在参数指定的字符序列之后。

异常

接受名为 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 时抛出的异常。

若因任何原因抛出异常,此函数不产生任何效果( 强异常安全保证 )。

可能的实现

重载版本 (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;
}

注释

对于不需要三路比较的情况, std::basic_string 提供了常规的 关系运算符 < , <= , == , > 等)。

默认情况下(使用默认的 std::char_traits ),此函数不具区域设置敏感性。有关支持区域设置的三路字符串比较,请参阅 std::collate::compare

示例

#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) << " 位于 "
                  << std::quoted(str2) << " 之前。\n";
    else if (compare_result > 0)
        std::cout << std::quoted(str2) << " 位于 "
                  << std::quoted(str1) << " 之前。\n";
    else
        std::cout << std::quoted(str1) << " 和 "
                  << std::quoted(str2) << " 相同。\n";
}
int main()
{
    std::string batman{"Batman"};
    std::string superman{"Superman"};
    int compare_result{0};
    // 1) 与其他字符串比较
    compare_result = batman.compare(superman);
    std::cout << "1) ";
    print_compare_result("Batman", "Superman", compare_result);
    // 2) 子串与其他字符串比较
    compare_result = batman.compare(3, 3, superman);
    std::cout << "2) ";
    print_compare_result("man", "Superman", compare_result);
    // 3) 子串与其他子串比较
    compare_result = batman.compare(3, 3, superman, 5, 3);
    std::cout << "3) ";
    print_compare_result("man", "man", compare_result);
    // 子串与其他子串比较
    // 默认使用其他字符串的末尾
    assert(compare_result == batman.compare(3, 3, superman, 5));
    // 4) 与字符指针比较
    compare_result = batman.compare("Superman");
    std::cout << "4) ";
    print_compare_result("Batman", "Superman", compare_result);
    // 5) 子串与字符指针比较
    compare_result = batman.compare(3, 3, "Superman");
    std::cout << "5) ";
    print_compare_result("man", "Superman", compare_result);
    // 6) 子串与字符指针子串比较
    compare_result = batman.compare(0, 3, "Superman", 5);
    std::cout << "6) ";
    print_compare_result("Bat", "Super", compare_result);
}

输出:

1) "Batman" 位于 "Superman" 之前。
2) "Superman" 位于 "man" 之前。
3) "man" 和 "man" 相同。
4) "Batman" 位于 "Superman" 之前。
5) "Superman" 位于 "man" 之前。
6) "Bat" 位于 "Super" 之前。

缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的C++标准。

缺陷报告 应用于 发布时的行为 正确行为
LWG 5 C++98 重载 (6) 的参数 count2
具有默认实参 npos
移除默认实参,
拆分为重载 (5) (6)
LWG 847 C++98 未提供异常安全保证 增加强异常安全保证
LWG 2946 C++17 重载 (7) 在某些情况下会导致歧义 通过将其设为模板来避免
P1148R0 C++17 重载 (7) 的 noexcept 在 LWG2946 的解决方案中
被意外丢弃
已恢复

参见

(C++20 中移除) (C++20 中移除) (C++20 中移除) (C++20 中移除) (C++20 中移除) (C++20)
按字典序比较两个字符串
(函数模板)
返回子字符串
(公开成员函数)
定义字符串的字典序比较和哈希
(类模板)
根据当前本地环境比较两个字符串
(函数)
若一个范围按字典序小于另一个则返回 true
(函数模板)
比较两个视图
( std::basic_string_view<CharT,Traits> 的公开成员函数)