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, |
(до C++14) | |
int compare( size_type pos1, size_type count1, const basic_string& str, |
(начиная с C++14) (до C++20) |
|
constexpr int compare( size_type pos1, size_type count1, const basic_string& str, |
(начиная с 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 |
(начиная с C++20) | |
(8) | ||
template< class StringViewLike > int compare( size_type pos1, size_type count1, |
(начиная с C++17) (до C++20) |
|
template< class StringViewLike > constexpr int compare( size_type pos1, size_type count1, |
(начиная с C++20) | |
(9) | ||
template< class StringViewLike > int compare( size_type pos1, size_type count1, |
(начиная с C++17) (до C++20) |
|
template< class StringViewLike > constexpr int compare( size_type pos1, size_type count1, |
(начиная с C++20) | |
Сравнивает две последовательности символов.
[
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())
.
[
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())
.
[
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::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, если аргумент выходит за пределы диапазона.
Если по какой-либо причине генерируется исключение, эта функция не имеет эффекта (строгая гарантия безопасности исключений).
[править] Возможная реализация
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> )
|