C++ 参考手册

位置:首页 > C++ 参考手册 >字符串库 >std::basic_string > std::basic_string<CharT,Traits,Allocator>::compare

             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 T >
int compare( const T& t ) const noexcept(/* see below */);
(C++17 起)
(C++20 前)
template < class T >
constexpr int compare( const T& t ) const noexcept(/* see below */);
(C++20 起) (8)
template < class T >

int compare( size_type pos1, size_type count1,

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

constexpr int compare( size_type pos1, size_type count1,

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

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

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

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

                       size_type pos2, size_type count2 = npos) const;
(C++20 起)

比较二个字符序列。

1) 比较此 string 与 str
2) 比较此 string 的 [pos1, pos1+count1) 子串与 str 。若 count1 > size() - pos1 则子串为 [pos1, size())
3) 比较此 string 的 [pos1, pos1+count1) 子串与 str 的子串 [pos2, pos2+count2) 。若 count1 > size() - pos1 则第一子串为 [pos1, size()) 。类似地若 count2 > str.size() - pos2 则第二子串为 [pos2, str.size())
4) 比较此 string 与始于 s 所指向字符的长度为 Traits::length(s) 的空终止字符序列。
5) 比较此 string 的 [pos1, pos1+count1) 子串与始于 s 所指向字符的长度为 Traits::length(s) 的空终止字符序列。若 count1 > size() - pos1 则子串为 [pos1, size())
6) 比较此 string 的 [pos1, pos1+count1) 子串与范围 [s, s + count2) 中的字符。(注意:范围 [s, s + count2) 中的字符可包含空字符。)
7) 如同用 std::basic_string_view<CharT, Traits> sv = t; 隐式转换 t 为 string_view sv ,然后比较此 string 与 sv 。此重载仅若 std::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>>truestd::is_convertible_v<const T&, const CharT*>false 才参与重载决议。
8) 如同用 std::basic_string_view<CharT, Traits> sv = t; 隐式转换 t 为 string_view sv ,然后比较此 string 的 [pos1, pos1+count1) 子串与 sv ,如同用 std::basic_string_view<CharT, Traits>(data(), size()).substr(pos1, count1).compare(sv) 。此重载仅若 std::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>>truestd::is_convertible_v<const T&, const CharT*>false 才参与重载决议。
9) 如同用 std::basic_string_view<CharT, Traits> sv = t; 隐式转换 t 为 string_view sv ,然后比较此 string 的 [pos1, pos1+count1) 子串与 sv[pos2, pos2+count2) 子串,如同用 std::basic_string_view<CharT, Traits>(data(), size()).substr(pos1, count1).compare(sv.substr(pos2, count2)); 。此重载仅若 std::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>>truestd::is_convertible_v<const T&, 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 - 要比较的另一 string
s - 指向要比较的字符串的指针
count1 - 此 string 要比较的字符数
pos1 - 此 string 中要比较的首字符的位置
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) 抛出任何到 basic_string_view 的转换所抛的异常。

可能的实现

template<class CharT, class Traits, class Alloc>
int 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

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR 应用于 出版时的行为 正确行为
LWG 2946 C++17 string_view 重载在某些情况下导致歧义 通过使之为模板来避免

示例

#include <cassert>
#include <string>
#include <iostream>
 
int main() 
{
    // 1) 与另一 string 比较
    {
        int compare_value{
            std::string{"Batman"}.compare(std::string{"Superman"})
        };
        std::cout << (
            compare_value < 0 ? "Batman comes before Superman\n" :
            compare_value > 0 ? "Superman comes before Batman\n" :
            "Superman and Batman are the same.\n"
        );
    }
 
    // 2) 与另一 string 比较子串
    {
        int compare_value{
            std::string{"Batman"}.compare(3, 3, std::string{"Superman"})
        };
        std::cout << (
            compare_value < 0 ? "man comes before Superman\n" :
            compare_value > 0 ? "Superman comes before man\n" :
            "man and Superman are the same.\n"
        );
    }
 
    // 3) 与另一子串比较子串
    {
        std::string a{"Batman"};
        std::string b{"Superman"};
 
        int compare_value{a.compare(3, 3, b, 5, 3)};
 
        std::cout << (
            compare_value < 0 ? "man comes before man\n" :
            compare_value > 0 ? "man comes before man\n" :
            "man and man are the same.\n"
        );
        // 与另一子串比较子串
        // 默认到为另一 string 的末尾
        assert(compare_value == a.compare(3, 3, b, 5));
    }
 
    // 4) 与另一 char 指针比较
    {
        int compare_value{std::string{"Batman"}.compare("Superman")};
 
        std::cout << (
            compare_value < 0 ? "Batman comes before Superman\n" :
            compare_value > 0 ? "Superman comes before Batman\n" :
            "Superman and Batman are the same.\n"
        );
    }
 
    // 5) 与另一 char 指针比较子串
    {
        int compare_value{std::string{"Batman"}.compare(3, 3, "Superman")};
 
        std::cout << (
            compare_value < 0 ? "man comes before Superman\n" :
            compare_value > 0 ? "Superman comes before man\n" :
            "man and Superman are the same.\n"
        );
    }
 
    // 6) 与另一 char 指针子串比较子串
    {
        int compare_value{std::string{"Batman"}.compare(0, 3, "Superman", 5)};
 
        std::cout << (
            compare_value < 0 ? "Bat comes before Super\n" :
            compare_value > 0 ? "Super comes before Bat\n" :
            "Super and Bat are the same.\n"
        );
    }
}

输出:

Batman comes before Superman
Superman comes before man
man and man are the same.
Batman comes before Superman
Superman comes before man
Bat comes before Super

参阅

(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)
以字典序比较两个字符串
(函数模板)
返回子串
(公开成员函数)
定义字典序比较和字符串的散列
(类模板)
按照当前本地环境比较两个字符串
(函数)
当一个范围按字典顺序小于另一个范围时,返回 true
(函数模板)