Пространства имён
Варианты
Действия

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

Материал из cppreference.com
< cpp‎ | string‎ | basic string
 
 
 
std::basic_string
Функции-элементы
Доступ к элементам
Итераторы
Ёмкость
Операции
basic_string::compare
Поиск
Константы
Правила вывода (C++17)
Функции, не являющиеся элементами
Ввод/Вывод
Сравнение
(до 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) текущей строки с подстрокой [pos2pos2 + count2) строки str.
  • Если 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) текущей строки с подстрокой [pos2pos2 + 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.

Если по какой-либо причине генерируется исключение, эта функция не имеет эффекта (строгая гарантия безопасности исключений).

[править] Возможная реализация

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++:

Номер Применён Поведение в стандарте Корректное поведение
LWG 5 C++98 параметр count2 перегрузки (6) имел аргумент
по умолчанию npos
аргумент по умолчанию удалён, разделив перегрузки
(5) и (6)
LWG 847 C++98 не было гарантии безопасности исключений добавлена надёжная гарантия безопасности исключений
LWG 2946 C++17 перегрузка (7) в некоторых случаях вызывала
двусмысленность
исправлено, сделав её шаблоном
WG не указан C++17 noexcept перегрузки (7) было случайно удалено
из-за разрешения LWG2946
восстановлено

[править] Смотрите также

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