std::basic_string<CharT,Traits,Allocator>::compare
From cppreference.com
< cpp | string | basic string
int compare( const basic_string& str ) const; |
(1) | (C++11 以降 noexcept) (C++20 以降 constexpr) |
int compare( size_type pos1, size_type count1, const basic_string& str ) const; |
(2) | (C++20 以降 constexpr) |
| (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( const CharT* s ) const; |
(4) | (C++20 以降 constexpr) |
int compare( size_type pos1, size_type count1, const CharT* s ) const; |
(5) | (C++20 以降 constexpr) |
int compare( size_type pos1, size_type count1, const CharT* s, size_type count2 ) const; |
(6) | (C++20 以降 constexpr) |
template< class StringViewLike > int compare( const StringViewLike& t ) const noexcept(/* see below */); |
(7) | (C++17以降) (C++20 以降 constexpr) |
template< class StringViewLike > int compare( size_type pos1, size_type count1, |
(8) | (C++17以降) (C++20 以降 constexpr) |
template< class StringViewLike > int compare( size_type pos1, size_type count1, |
(9) | (C++17以降) (C++20 以降 constexpr) |
2つの文字シーケンスを比較します。
1) この文字列と str を比較します。
2) この文字列の
[pos1, pos1 + count1) の部分文字列と str を比較します。- もし count1 > size() - pos1 ならば、部分文字列は
[pos1,size())となります。
3) この文字列の
[pos1, pos1 + count1) の部分文字列と、str の [pos2, pos2 + count2) の部分文字列を比較します。- もし count1 > size() - pos1 ならば、最初の部分文字列は
[pos1,size())となります。 - もし count2 > str.size() - pos2 ならば、2番目の部分文字列は
[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) この文字列と sv を比較します。
8) この文字列の
[pos1, pos1 + count1) の部分文字列と sv を、あたかも std::basic_string_view<CharT, Traits>(*this).substr(pos1, count1).compare(sv) のように比較します。9) この文字列の
.substr(pos1, count1).compare(sv.substr(pos2, count2)) のように比較します。
[pos1, pos1 + count1) の部分文字列と、sv の [pos2, pos2 + count2) の部分文字列を、あたかも std::basic_string_view<CharT, Traits>(*this).substr(pos1, count1).compare(sv.substr(pos2, count2)) のように比較します。
これらのオーバーロードは、const StringViewLike& が std::is_convertible_v<const StringViewLike&,
std::basic_string_view<CharT, Traits>> に変換可能であり、かつ、const StringViewLike& が std::is_convertible_v<const StringViewLike&, const CharT*> に変換不可能である場合にのみ、オーバーロード解決に参加します。
std::basic_string_view<CharT, Traits>> に変換可能であり、かつ、const StringViewLike& が std::is_convertible_v<const StringViewLike&, const CharT*> に変換不可能である場合にのみ、オーバーロード解決に参加します。
data1 から始まる count1 文字の文字シーケンスと、data2 から始まる count2 文字の文字シーケンスは、以下のように比較されます。
- まず、比較する文字数を、あたかも 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 | - | 比較対象の C 文字列へのポインタ |
| 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; } |
[編集] ノート
3方向比較が必要ない場合は、std::basic_string は通常の 比較演算子(<、<=、==、> など)を提供します。
デフォルト(デフォルトの std::char_traits を使用)では、この関数はロケールに依存しません。std::collate::compare を参照してください。ロケール対応の3方向文字列比較については。
[編集] 例
このコードを実行
#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 | オーバーロード (6) のパラメータ count2 にはデフォルト引数 npos がありました。 |
デフォルト引数は削除され、 オーバーロード (5) と (6) に分割されました。 |
| LWG 847 | C++98 | 例外安全性保証がなかった | 強力な例外安全性保証を追加 |
| LWG 2946 | C++17 | オーバーロード (7) は、一部のケースで曖昧さを引き起こしました。 | テンプレートにすることで回避されました。 |
| P1148R0 | C++17 | オーバーロード (7) の noexcept は、LWG2946 の解決によって誤って 削除されました。 |
復元されました。 |
[編集] 関連情報
| (C++20で削除)(C++20で削除)(C++20で削除)(C++20で削除)(C++20で削除)(C++20) |
2つの文字列を辞書順で比較する (function template) |
| 部分文字列を返す (public member function) | |
| 文字列の辞書順比較とハッシュ化を定義する (クラステンプレート) | |
| 現在のロケールに従って2つの文字列を比較する (関数) | |
| ある範囲が別の範囲より辞書順で小さい場合に true を返す (関数テンプレート) | |
| 2つのビューを比較する ( std::basic_string_view<CharT,Traits> の public メンバ関数) |