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

来自cppreference.com
< cpp‎ | string‎ | basic string
 
 
 
std::basic_string
成员函数
元素访问
迭代器
容量
操作
basic_string::compare
搜索
常量
推导指引 (C++17)
非成员函数
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)
辅助类
 
(1)
int compare( const basic_string& str ) const;
(C++11 前)
int compare( const basic_string& str ) const noexcept;
(C++11 起)
(C++20 前)
constexpr int compare( const basic_string& str ) const noexcept;
(C++20 起)
(2)
int compare( size_type pos1, size_type count1,
             const basic_string& str ) const;
(C++20 前)
constexpr int compare( size_type pos1, size_type count1,
                       const basic_string& str ) const;
(C++20 起)
(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( size_type pos1, size_type count1,

                       const basic_string& str,

                       size_type pos2, size_type count2 = npos ) const;
(C++20 起)
(4)
int compare( const CharT* s ) const;
(C++20 前)
constexpr int compare( const CharT* s ) const;
(C++20 起)
(5)
int compare( size_type pos1, size_type count1,
             const CharT* s ) const;
(C++20 前)
constexpr int compare( size_type pos1, size_type count1,
                       const CharT* s ) const;
(C++20 起)
(6)
int compare( size_type pos1, size_type count1,
             const CharT* s, size_type count2 ) const;
(C++20 前)
constexpr int compare( size_type pos1, size_type count1,
                       const CharT* s, size_type count2 ) const;
(C++20 起)
(7)
template < class StringViewLike >
int compare( const StringViewLike& t ) const noexcept(/* 见下文 */);
(C++17 起)
(C++20 前)
template < class StringViewLike >
constexpr int compare( const StringViewLike& t ) const noexcept(/* 见下文 */);
(C++20 起)
(8)
template < class StringViewLike >

int compare( size_type pos1, size_type count1,

             const StringViewLike& t ) const;
(C++17 起)
(C++20 前)
template < class StringViewLike >

constexpr int compare( size_type pos1, size_type count1,

                       const StringViewLike& t ) const;
(C++20 起)
(9)
template < class StringViewLike >

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

             size_type pos2, size_type count2 = npos) const;
(C++17 起)
(C++20 前)
template < class StringViewLike >

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

                       size_type pos2, size_type count2 = npos) const;
(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,那么子串是 [pos1, size())
6) 比较此字符串的 [pos1pos1 + count1) 子串与范围 [ss + count2) 中的字符。[ss + count2) 中的字符可包含空字符。
  • 如果 count1 > size() - pos1,那么子串是 [pos1size())
7-9) 如同用 std::basic_string_view<CharT, Traits> sv = t;t 隐式转换到字符串视图 sv ,然后
7) 比较此字符串与 sv
8) 如同用 std::basic_string_view<CharT, Traits>(data(), size())
    .substr(pos1, count1).compare(sv)

比较此字符串的 [pos1pos1 + count1) 子串与 sv
9) 如同用 std::basic_string_view<CharT, Traits>(*this)
    .substr(pos1, count1).compare(sv.substr(pos2, count2))

比较此字符串的 [pos1pos1 + count1) 子串与 sv[pos2pos2 + count2) 子串。
这些重载只有在 std::is_convertible_v<const StringViewLike&,
                      std::basic_string_view<CharT, Traits>>
truestd::is_convertible_v<const StringViewLike&, const CharT*>false 时才会参与重载决议。

按下列方式比较始于 data1count1 个字符组成的字符序列与始于 data2count2 个字符组成的字符序列。首先,如同用 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 在字典序中后出现于参数所指定的字符序列时是正值。

异常

接收名为 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 的转换所抛的异常。

如果因为任何原因抛出了异常,那么此函数无效果(强异常安全保证)。

可能的实现

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();
    if (int result = traits_type::compare(data(), s.data(), std::min(lhs_sz, rhs_sz)))
        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 <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 << str1 << " 在 " << str2 << " 前面。\n";
    else if (compare_result > 0)
        std::cout << str2 << " 在 " << str1 << " 前面。\n";
    else
        std::cout << str1 << " 和 " << 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) 与另一 char 指针比较
    compare_result = batman.compare("Superman");
    std::cout << "4) ";
    print_compare_result("Batman", "Superman", compare_result);
 
    // 5) 与另一 char 指针比较子串
    compare_result = batman.compare(3, 3, "Superman");
    std::cout << "5) ";
    print_compare_result("man", "Superman", compare_result);
 
    // 6) 与另一 char 指针子串比较子串
    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
(函数模板)