std::basic_string::compare(3)
π
std::basic_string::compare(3) β C++ Standard Libary π
okay bestie, part 1 of 2, and we are doing std::basic_string::compare from the C++ Standard Libary. This is the βwho comes first in lexicographical orderβ girlie. No cap, she compares two character sequences and gives you <0, 0, or >0. The vibes are immaculate, the facts are unchanged. β¨
πΈ NAME πΈ
std::basic_string::compare
β¨ SYNOPSIS β¨
Hereβs the whole overload lineup with every version tag, bestie. π
// (1) noexcept since C++11, constexpr since C++20
int compare( const basic_string& str ) const;
// (2) constexpr since C++20
int compare( size_type pos1, size_type count1, const basic_string& str ) const;
// (3) until C++14
int compare( size_type pos1, size_type count1,
const basic_string& str,
size_type pos2, size_type count2 ) const;
// (3) since C++14, constexpr since C++20
int compare( size_type pos1, size_type count1,
const basic_string& str,
size_type pos2, size_type count2 = npos ) const;
// (4) constexpr since C++20
int compare( const CharT* s ) const;
// (5) constexpr since C++20
int compare( size_type pos1, size_type count1,
const CharT* s ) const;
// (6) constexpr since C++20
int compare( size_type pos1, size_type count1,
const CharT* s, size_type count2 ) const;
// (7) since C++17, constexpr since C++20
template< class StringViewLike >
int compare( const StringViewLike& t ) const
noexcept(/* see below */);
// (8) since C++17, constexpr since C++20
template< class StringViewLike >
int compare( size_type pos1, size_type count1,
const StringViewLike& t ) const;
// (9) since C++17, constexpr since C++20
template< class StringViewLike >
int compare( size_type pos1, size_type count1,
const StringViewLike& t,
size_type pos2, size_type count2 = npos) const;
Compares two character sequences
- Compares this string to
str. - Compares a
[pos1, pos1 + count1)substring of this string tostr.- If
count1 > size() - pos1, the substring is[pos1, size()).
- If
- Compares a
[pos1, pos1 + count1)substring of this string to a substring[pos2, pos2 + count2)ofstr.- If
count1 > size() - pos1, the first substring is[pos1, size()). - If
count2 > str.size() - pos2, the second substring is[pos2, str.size()).
- If
- Compares this string to the null-terminated character sequence beginning at the character pointed to by
swith lengthTraits::length(s). - Compares a
[pos1, pos1 + count1)substring of this string to the null-terminated character sequence beginning at the character pointed to byswith lengthTraits::length(s).- If
count1 > size() - pos1, the substring is[pos1, size()).
- If
- Compares a
[pos1, pos1 + count1)substring of this string to the characters in the range[s, s + count2). The characters in[s, s + count2)may include null characters.- If
count1 > size() - pos1, the substring is[pos1, size()). 7-9. Implicitly convertstto a string viewsvas if bystd::basic_string_view<CharT, Traits> sv = t;, then: - 7) compares this string to
sv; - 8) compares a
[pos1, pos1 + count1)substring of this string tosv, as if bystd::basic_string_view<CharT, Traits>(*this).substr(pos1, count1).compare(sv); - 9) compares a
[pos1, pos1 + count1)substring of this string to a substring[pos2, pos2 + count2)ofsv, as if bystd::basic_string_view<CharT, Traits>(*this).substr(pos1, count1).compare(sv.substr(pos2, count2)). - These overloads participate in overload resolution only if
std::is_convertible_v<const StringViewLike&, std::basic_string_view<CharT, Traits>>is true andstd::is_convertible_v<const StringViewLike&, const CharT*>is false.
- If
A character sequence consisting of count1 characters starting at data1 is compared to a character sequence consisting of count2 characters starting at data2 as follows:
- First, calculate the number of characters to compare, as if by
size_type rlen = std::min(count1, count2). - Then compare the sequences by calling
Traits::compare(data1, data2, rlen). For standard strings this function performs character-by-character lexicographical comparison. If the result is zero (the character sequences are equal so far), then their sizes are compared as follows: - If
Traits::compare(data1, data2, rlen) < 0, thendata1is less thandata2, and the return value is<0. - If
Traits::compare(data1, data2, rlen) == 0andsize1 < size2, thendata1is less thandata2, and the return value is<0. - If
Traits::compare(data1, data2, rlen) == 0andsize1 == size2, thendata1is equal todata2, and the return value is0. - If
Traits::compare(data1, data2, rlen) == 0andsize1 > size2, thendata1is greater thandata2, and the return value is>0. - If
Traits::compare(data1, data2, rlen) > 0, thendata1is greater thandata2, and the return value is>0.
π«Ά PARAMETERS π«Ά
strβ other string to compare tosβ pointer to the character string to compare tocount1β number of characters of this string to comparepos1β position of the first character in this string to comparecount2β number of characters of the given string to comparepos2β position of the first character of the given string to comparetβ object (convertible tostd::basic_string_view) to compare to
π RETURN VALUE π
- Negative value if
*thisappears before the character sequence specified by the arguments, in lexicographical order. - Zero if both character sequences compare equivalent.
- Positive value if
*thisappears after the character sequence specified by the arguments, in lexicographical order.
π EXCEPTIONS π
The overloads taking parameters named pos1 or pos2 throw std::out_of_range if the argument is out of range.
- 7)
noexceptspecification:noexcept(std::is_nothrow_convertible_v<const T&, std::basic_string_view<CharT, Traits>>) - 8,9) Throws anything thrown by the conversion to
std::basic_string_view.
If an exception is thrown for any reason, this function has no effect (strong exception safety guarantee).
π POSSIBLE IMPLEMENTATION π
overload (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;
}
π¦ NOTES π¦
For the situations when three-way comparison is not required, std::basic_string provides the usual relational operators (<, <=, ==, >, etc).
By default (with the default std::char_traits), this function is not locale-sensitive. See std::collate::compare for locale-aware three-way string comparison.
π EXAMPLE π
// Run this code
#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);
}
Output π
okay so here's what falls out of the terminal when that example runs, one line per case, and the whole point is that lexicographic order is not the same as "human alphabetical vibes" β uppercase letters sit before lowercase in the character set, so Superman slides in ahead of man, no cap:
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".
like look at 2) and 5) β same verdict both times, and it's the one everybody gets wrong on the first try π The B/S/m ordering is doing all the work. And 6) is just the classic prefix situation: "Bat" is a prefix of "Super"? no bestie, it's shorter and sorts first because the shorter string wins when everything up to its length matches β which it doesn't here, but the line still shows the shorter-one-first habit of the comparison π
π Defect reports
these are the "oops we said it wrong back then" receipts β the following behavior-changing defect reports were applied retroactively to previously published C++ standards:
LWG 5β applied to C++98. behavior as published: the parametercount2of overload(6)had a default argumentnpos. correct behavior: default argument removed, split to overloads(5)and(6)β¨LWG 847β applied to C++98. behavior as published: there was no exception safety guarantee. correct behavior: added strong exception guarantee π«ΆLWG 2946β applied to C++17. behavior as published: overload(7)caused ambiguity in some cases. correct behavior: avoided by making it a template π₯P1148R0β applied to C++17. behavior as published:noexceptfor overload(7)was accidentally dropped by the resolution ofLWG2946. correct behavior: restored π
fr fr, P1148R0 is the "we broke it while fixing it and then fixed the fix" entry and honestly it's so real of the committee π
π See also
the whole friend group of comparison-adjacent things, all linked up:
operator==,operator!=,operator<,operator>,operator<=,operator>=β lexicographically compares two strings (function template)- five of these rows carry a
(removed in C++20)tag in the table, so keep that in your notes π
- five of these rows carry a
operator<=>β(C++20)substrβ returns a substring (public member function)collateβ defines lexicographical comparison and hashing of strings (class template)strcollβ compares two strings in accordance to the current locale (function)lexicographical_compareβ returns true if one range is lexicographically less than another (function template)compareβ compares two views (public member function ofstd::basic_string_view<CharT,Traits>)
π¦ Category
* conditionally noexcept
okay that's the whole page, bestie β you made it to the end, which is genuinely iconic of you π go call compare on something and let it sort your life out β¨
and the boring-but-important bit, delivered cute: this whole thing is from cppreference.com, dated 2024.06.10, and the page is std::basic_string::compare(3). stan the reference site, it's the real main character ππ
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms