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 T > int compare( const T& t ) const noexcept(/* see below */); |
(C++17以上) (C++20未満) |
|
template < class T > constexpr int compare( const T& t ) const noexcept(/* see below */); |
(C++20以上) | |
| (8) | ||
template < class T > int compare( size_type pos1, size_type count1, const T& t ) const; |
(C++17以上) (C++20未満) |
|
template < class T > constexpr int compare( size_type pos1, size_type count1, const T& t ) const; |
(C++20以上) | |
| (9) | ||
template < class T > int compare( size_type pos1, size_type count1, const T& t, size_type pos2, size_type count2 = npos) const; |
(C++17以上) (C++20未満) |
|
template < class T > constexpr int compare( size_type pos1, size_type count1, const T& t, size_type pos2, size_type count2 = npos) const; |
(C++20以上) | |
2つの文字シーケンスを比較します。
[pos1, pos1+count1) の部分文字列を str と比較します。 count1 > size() - pos1 の場合は部分文字列は [pos1, size()) です。[pos1, pos1+count1) の部分文字列を str の [pos2, pos2+count2) の部分文字列と比較します。 count1 > size() - pos1 の場合は1つめの部分文字列は [pos1, size()) です。 同様に count2 > str.size() - pos2 の場合は2つめの部分文字列は [pos2, str.size()) です。Traits::length(s) のヌル終端文字シーケンスと比較します。[pos1, pos1+count1) の部分文字列を s の指す文字から始まる長さ Traits::length(s) のヌル終端文字シーケンスと比較します。 count1 > size() - pos1 の場合は部分文字列は [pos1, size()) です。[pos1, pos1+count1) の部分文字列を範囲 [s, s + count2) 内の文字と比較します。 If count1 > size() - pos1 the substring is [pos1, size()). (Note: the characters in the range [s, s + count2) may include null characters.)std::basic_string_view<CharT, Traits> sv = t; によって行われたかのように、 t を文字列ビュー sv に暗黙に変換し、 この文字列を sv と比較します。 このオーバーロードは、std::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>> が true であり、 std::is_convertible_v<const T&, const CharT*> が false である場合にのみ、オーバーロード解決に参加します。std::basic_string_view<CharT, Traits> sv = t; によって行われたかのように、 t を文字列ビュー sv に暗黙に変換し、 std::basic_string_view<CharT, Traits>(*this).substr(pos1, count1).compare(sv) によって行われたかのように、この文字列の [pos1, pos1+count1) の部分文字列を sv 比較します。 このオーバーロードは、std::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>> が true であり、 std::is_convertible_v<const T&, const CharT*> が false である場合にのみ、オーバーロード解決に参加します。std::basic_string_view<CharT, Traits> sv = t; によって行われたかのように、 t を文字列ビュー sv に暗黙に変換し、 std::basic_string_view<CharT, Traits>(*this).substr(pos1, count1).compare(sv.substr(pos2, count2)) によって行われたかのように、この文字列の [pos1, pos1+count1) の部分文字列を sv の [pos2, pos2+count2) の部分文字列と比較します。。 このオーバーロードは、std::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>> が true であり、 std::is_convertible_v<const T&, const CharT*> が false である場合にのみ、オーバーロード解決に参加します。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 | - | 比較する文字列を指すポインタ |
| 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>>)basic_string_view への変換によって投げられるあらゆる例外を投げます。欠陥報告
以下の動作変更欠陥報告は以前に発行された C++ 標準に遡って適用されました。
| DR | 適用先 | 発行時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 2946 | C++17 | string_view overload causes ambiguity in some cases
|
avoided by making it a template |
実装例
template<class CharT, class Traits, class Alloc>
int 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 <string>
#include <iostream>
int main()
{
// 1) 他の文字列と比較します。
{
int compare_value{
std::string{"Batman"}.compare(std::string{"Superman"})
};
std::cout << (
compare_value < 0 ? "Batman comes before Superman\n" :
compare_value > 0 ? "Superman comes before Batman\n" :
"Superman and Batman are the same.\n"
);
}
// 2) 部分文字列を他の文字列と比較します。
{
int compare_value{
std::string{"Batman"}.compare(3, 3, std::string{"Superman"})
};
std::cout << (
compare_value < 0 ? "man comes before Superman\n" :
compare_value > 0 ? "Superman comes before man\n" :
"man and Superman are the same.\n"
);
}
// 3) 部分文字列を他の部分文字列と比較します。
{
std::string a{"Batman"};
std::string b{"Superman"};
int compare_value{a.compare(3, 3, b, 5, 3)};
std::cout << (
compare_value < 0 ? "man comes before man\n" :
compare_value > 0 ? "man comes before man\n" :
"man and man are the same.\n"
);
// 部分文字列を他の部分文字列と比較します。
// デフォルト値 (他の文字列の終端まで) を使用しています。
assert(compare_value == a.compare(3, 3, b, 5));
}
// 4) char ポインタと比較します。
{
int compare_value{std::string{"Batman"}.compare("Superman")};
std::cout << (
compare_value < 0 ? "Batman comes before Superman\n" :
compare_value > 0 ? "Superman comes before Batman\n" :
"Superman and Batman are the same.\n"
);
}
// 5) 部分文字列を char ポインタと比較します。
{
int compare_value{std::string{"Batman"}.compare(3, 3, "Superman")};
std::cout << (
compare_value < 0 ? "man comes before Superman\n" :
compare_value > 0 ? "Superman comes before man\n" :
"man and Superman are the same.\n"
);
}
// 6) 部分文字列を char ポインタの部分文字列と比較します。
{
int compare_value{std::string{"Batman"}.compare(0, 3, "Superman", 5)};
std::cout << (
compare_value < 0 ? "Bat comes before Super\n" :
compare_value > 0 ? "Super comes before Bat\n" :
"Super and Bat are the same.\n"
);
}
}
出力:
Batman comes before Superman
Superman comes before man
man and man are the same.
Batman comes before Superman
Superman comes before man
Bat comes before Super
