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(/* смотрите ниже */); |
(начиная с 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) | |
Сравнивает две последовательности символов.
str.[pos1, pos1 + count1) текущей строки с str.
- Если
count1 > size() - pos1, подстрока равна[pos1,size()).
[pos1, pos1 + count1) текущей строки с подстрокой [pos2, pos2 + count2) строки str.
- Если
count1 > size() - pos1, первая подстрока равна[pos1,size()). - Если
count2 > str.size() - pos2, вторая подстрока равна[pos2,str.size()).
s, с длиной Traits::length(s).[pos1, pos1 + count1) текущей строки с последовательностью символов, завершающейся нулём, начиная с символа, на который указывает s, с длиной Traits::length(s).
- Если
count1 > size() - pos1, подстрока равна[pos1,size()).
[pos1, pos1 + count1) текущей строки с символами в диапазоне [s, s + count2). Символы в [s, s + count2) могут включать нулевые символы.
- Если
count1 > size() - pos1, подстрока равна[pos1,size()).
t в строковое представление sv, как если бы с помощью std::basic_string_view<CharT, Traits> sv = t;, затем sv;[pos1, pos1 + count1) текущей строки с sv, как если бы с помощью std::basic_string_view<CharT, Traits>(*this).substr(pos1, count1).compare(sv);[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, если аргумент выходит за пределы диапазона.
noexcept(std::is_nothrow_convertible_v<const T&, std::basic_string_view<CharT, Traits>>)Если по какой-либо причине генерируется исключение, эта функция не имеет эффекта (строгая гарантия безопасности исключений).
Возможная реализация
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>)
|