名前空間
変種
操作

std::basic_string<CharT,Traits,Allocator>::compare

From cppreference.com
< cpp‎ | string‎ | basic string
 
 
 
std::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,

             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( 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,

             const StringViewLike& t ) const;
(8) (C++17以降)
(C++20 以降 constexpr)
template< class StringViewLike >

int compare( size_type pos1, size_type count1,
             const StringViewLike& t,

             size_type pos2, size_type count2 = npos) const;
(9) (C++17以降)
(C++20 以降 constexpr)

2つの文字シーケンスを比較します。

1) この文字列と str を比較します。
2) この文字列の [pos1pos1 + count1) の部分文字列と str を比較します。
  • もし count1 > size() - pos1 ならば、部分文字列は [pos1size()) となります。
3) この文字列の [pos1pos1 + count1) の部分文字列と、str[pos2pos2 + count2) の部分文字列を比較します。
  • もし count1 > size() - pos1 ならば、最初の部分文字列は [pos1size()) となります。
  • もし count2 > str.size() - pos2 ならば、2番目の部分文字列は [pos2str.size()) となります。
4) この文字列と、s が指す文字から始まるヌル終端の文字シーケンス(長さは Traits::length(s))を比較します。
5) この文字列の [pos1pos1 + count1) の部分文字列と、s が指す文字から始まるヌル終端の文字シーケンス(長さは Traits::length(s))を比較します。
  • もし count1 > size() - pos1 ならば、部分文字列は [pos1size()) となります。
6) この文字列の [pos1pos1 + count1) の部分文字列と、s から s + count2 までの範囲にある文字を比較します。範囲 [ss + count2) にはヌル文字が含まれることがあります。
  • もし count1 > size() - pos1 ならば、部分文字列は [pos1size()) となります。
7-9) t を、あたかも std::basic_string_view<CharT, Traits> sv = t; のように文字列ビュー sv に暗黙的に変換し、その後、
7) この文字列と sv を比較します。
8) この文字列の [pos1pos1 + count1) の部分文字列と sv を、あたかも std::basic_string_view<CharT, Traits>(*this).substr(pos1, count1).compare(sv) のように比較します。
9) この文字列の [pos1pos1 + count1) の部分文字列と、sv[pos2pos2 + 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*> に変換不可能である場合にのみ、オーバーロード解決に参加します。

data1 から始まる count1 文字の文字シーケンスと、data2 から始まる count2 文字の文字シーケンスは、以下のように比較されます。

  • まず、比較する文字数を、あたかも size_type rlen = std::min(count1, count2) で計算します。
  • 次に、Traits::compare(data1, data2, rlen) を呼び出してシーケンスを比較します。標準文字列の場合、この関数は文字ごとの辞書順比較を実行します。結果がゼロ(それまでの文字シーケンスが等しい)の場合、サイズを次のように比較します。
条件 結果 戻り値
Traits::compare(data1, data2, rlen) < 0 data1data2 より *小さい* <0
Traits::compare(data1, data2, rlen) == 0 size1 < size2 data1data2 より *小さい* <0
size1 == size2 data1data2 と *等しい* 0
size1 > size2 data1data2 より *大きい* >0
Traits::compare(data1, data2, rlen) > 0 data1data2 より *大きい* >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 メンバ関数) [編集]
English 日本語 中文(简体) 中文(繁體)