Namespaces
Variants

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

From ru.cppreference.net
 
 
 
std::basic_string
 
int compare( const basic_string& str ) const;
(1) (noexcept начиная с C++11)
(constexpr начиная с C++20)
int compare( size_type pos1, size_type count1,
             const basic_string& str ) const;
(2) (constexpr начиная с C++20)
int compare( size_type pos1, size_type count1,
             const basic_string& str,
             size_type pos2, size_type count2 ) const;
(3) (до C++14)
int compare( size_type pos1, size_type count1,
             const basic_string& str,
             size_type pos2, size_type count2 = npos ) const;
(начиная с C++14)
(constexpr начиная с C++20)
int compare( const CharT* s ) const;
(4) (constexpr начиная с C++20)
int compare( size_type pos1, size_type count1,
             const CharT* s ) const;
(5) (constexpr начиная с C++20)
int compare( size_type pos1, size_type count1,
             const CharT* s, size_type count2 ) const;
(6) (constexpr начиная с C++20)
template< class StringViewLike >
int compare( const StringViewLike& t ) const noexcept(/* see below */);
(7) (начиная с C++17)
(constexpr начиная с C++20)
template< class StringViewLike >
int compare( size_type pos1, size_type count1,
             const StringViewLike& t ) const;
(8) (начиная с C++17)
(constexpr начиная с 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) (начиная с C++17)
(constexpr начиная с C++20)

Сравнивает две последовательности символов.

1) Сравнивает эту строку с str.
2) Сравнивает [pos1, pos1 + count1) подстроку этой строки с str.
  • Если count1 > size() - pos1, подстрока равна [pos1, size()).
3) Сравнивает [pos1, pos1 + count1) подстроку этой строки с подстрокой [pos2, pos2 + count2) строки str.
  • Если count1 > size() - pos1, первая подстрока равна [pos1, size()).
  • Если count2 > str.size() - pos2, вторая подстрока равна [pos2, str.size()).
4) Сравнивает эту строку с null-терминированной последовательностью символов, начинающейся с символа, на который указывает s, длиной Traits::length(s).
5) Сравнивает [pos1, pos1 + count1) подстроку этой строки с null-терминированной последовательностью символов, начинающейся с символа, на который указывает s, длиной Traits::length(s).
  • Если count1 > size() - pos1, подстрока равна [pos1, size()).
6) Сравнивает [pos1, pos1 + count1) подстроку этой строки с символами в диапазоне [s, s + count2). Символы в [s, s + count2) могут содержать null-символы.
  • Если 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) подстроку этой строки с подстрокой [pos2, pos2 + count2) строки sv, как если бы с помощью 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.

Последовательность символов, состоящая из 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

Параметры

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) Сравнение с указателем на 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++.

DR Applied to Behavior as published Correct behavior
LWG 5 C++98 параметр count2 перегрузки (6)
имел аргумент по умолчанию npos
аргумент по умолчанию удалён,
разделено на перегрузки (5) и (6)
LWG 847 C++98 не было гарантии безопасности исключений добавлена строгая гарантия безопасности исключений
LWG 2946 C++17 перегрузка (7) вызывала неоднозначность в некоторых случаях устранено путём преобразования в шаблон
P1148R0 C++17 спецификатор noexcept для перегрузки (7) был случайно
удалён при решении LWG2946
восстановлен

См. также

(удалено в C++20)(удалено в C++20)(удалено в C++20)(удалено в C++20)(удалено в C++20)(C++20)
лексикографически сравнивает две строки
(шаблон функции)
возвращает подстроку
(публичная функция-элемент)
определяет лексикографическое сравнение и хеширование строк
(шаблон класса)
сравнивает две строки в соответствии с текущей локалью
(функция)
лексикографически сравнивает два диапазона
(шаблон функции & объект алгоритмической функции)
сравнивает два представления
(публичная функция-элемент std::basic_string_view<CharT,Traits>)