Spec-Zone.ru › C++

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

(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(/* see below */);
(с C++17)
(до C++20)
template< class StringViewLike >
constexpr int
    compare( const StringViewLike& t ) const noexcept(/* see below */);
(с 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) Сравнивает [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) Сравнивает эту строку с последовательностью символов с нулевым завершением, начинающейся с символа, на который указывает 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) подстроку этой строки с подстрокой [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.

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

Возможная реализация

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) << " comes before "
                  << std::quoted(str2) << ".\n";
    else if (compare_result > 0)
        std::cout << std::quoted(str2) << " comes before "
                  << std::quoted(str1) << ".\n";
    else
        std::cout << std::quoted(str1) << " and "
                  << std::quoted(str2) << " are the same.\n";
}
 
int main()
{
    std::string batman{"Batman"};
    std::string superman{"Superman"};
    int compare_result{0};
 
    // 1) Compare with other string
    compare_result = batman.compare(superman);
    std::cout << "1) ";
    print_compare_result("Batman", "Superman", compare_result);
 
    // 2) Compare substring with other string
    compare_result = batman.compare(3, 3, superman);
    std::cout << "2) ";
    print_compare_result("man", "Superman", compare_result);
 
    // 3) Compare substring with other substring
    compare_result = batman.compare(3, 3, superman, 5, 3);
    std::cout << "3) ";
    print_compare_result("man", "man", compare_result);
 
    // Compare substring with other substring
    // defaulting to end of other string
    assert(compare_result == batman.compare(3, 3, superman, 5));
 
    // 4) Compare with char pointer
    compare_result = batman.compare("Superman");
    std::cout << "4) ";
    print_compare_result("Batman", "Superman", compare_result);
 
    // 5) Compare substring with char pointer
    compare_result = batman.compare(3, 3, "Superman");
    std::cout << "5) ";
    print_compare_result("man", "Superman", compare_result);
 
    // 6) Compare substring with char pointer substring
    compare_result = batman.compare(0, 3, "Superman", 5);
    std::cout << "6) ";
    print_compare_result("Bat", "Super", compare_result);
}

Вывод:

1) "Batman" comes before "Superman".
2) "Superman" comes before "man".
3) "man" and "man" are the same.
4) "Batman" comes before "Superman".
5) "Superman" comes before "man".
6) "Bat" comes before "Super".

Отчёты о дефектах

Следующие отчёты о дефектах, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

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

См. также

operator==operator!=operator<operator>operator<=operator>=operator<=>
(удалено в C++20)(удалено в C++20)(удалено в C++20)(удалено в C++20)(удалено в C++20)(C++20)
лексикографически сравнивает две строки
(шаблон функции)
substr
возвращает подстроку
(публичный член-функция)
collate
определяет лексикографическое сравнение и хеширование строк
(шаблон класса)
strcoll
сравнивает две строки в соответствии с текущей локалью
(функция)
lexicographical_compare
возвращает true если один диапазон лексикографически меньше другого
(шаблон функции)
compare
сравнивает два представления
(публичный член-функция std::basic_string_view<CharT,Traits>)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/string/basic_string/compare

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API