Spec-Zone.ru › C++

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

int compare( const basic_string& str ) const;
(1) (без исключений начиная с 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) Сравнивает эту строку с последовательностью символов, завершающейся нулевым символом и начинающейся с символа, на который указывает 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.

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

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

перегрузка (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) << " 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++.

Отчет об ошибке Применяется к Опубликованное поведение Корректное поведение
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
лексикографически сравнивает два диапазона
(шаблон функции и функциональный объект алгоритма)
ranges::lexicographical_compare
(C++20)
compare
сравнивает два представления
(открытая функция-член std::basic_string_view<CharT,Traits>)

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

Spec-Zone.ru

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