2013-02-12 3 views
10

std::stringにはfindのメンバー機能があり、std::vectorと友だちにはメンバー機能がないのはなぜですか?なぜ `std :: string`は` find`メンバ関数を持っていますか?

文字列にstd::findを使用すると何か問題がありますか?

+13

http://www.gotw.ca/gotw/084.htm – juanchopanza

+2

@juanchopanzaすごいことは素晴らしいリンクで綴られたかのようにstd::stringを読みます。 (非会員の友人がカプセル化を改善する方法について多くのことを学んだ。(著者から読まれなかった人は、std :: list、std :: vector、std: :文字列と標準ライブラリ全体を扱う1つの汎用関数になります)。 – nckturner

答えて

12

これは主に歴史的な理由によるものですが、それだけではありません。

文字列ライブラリとSTL(A. Stepanovによって開発されたC++標準ライブラリの一部となったコンテナ/アルゴリズムライブラリ)は独自に開発され、異なる規則を採用しました。彼らは最終的には両方のC++標準ライブラリに収束しかし、C++標準は、これらの構文規則を統一する努力を行い、STLアルゴリズムとstring Sを使用でき、クラスstringは、begin()としてメンバ関数を有している理由であると

他のメンバー機能(例えば、substr())とは別に、end()

以外の下位互換性から、とにかく、stringは、find()としてメンバ関数を提供して別の理由があります:アクセスしたり、自分の要素を操作する汎用アルゴリズムで動作するように意図されているコンテナとは異なり、文字列がほとんどのように考えられているが、値はのコレクション(すなわち、charのシーケンス)ではなく、値自体です。したがって、stringの値を操作するアルゴリズムをstringクラスのメンバ関数にカプセル化することは理にかなっています。

したがって、C++標準ライブラリは、stringのこれらのビューの両方を、値のコレクションと値そのものとしてサポートしています。

UPDATE:あなたの最初の文の

ビット完全に間違っています「std::vectorや友人はそれがありませんが」。少なくとも、std::vectorの友人の範囲をstd::set,std::multisetstd::mapstd::multimapstd::unordered_set、およびstd::unordered_map(つまり、C++標準ライブラリのほぼすべての関連するコンテナ)にまで延長してはいけません。

特定のデータ構造は実際には、インターフェース上にいくつかの一般的なSTLアルゴリズムのメンバ関数バージョンを持っています:これは、それらのアルゴリズムが特定のデータ構造の一般的なものよりも効率的な実装をしていることを示します。 find())、汎用アルゴリズムをそれらのデータ構造に全く適用することができないため(例えば、std::remove()がコンテナ内の値をに変更するため)、特殊な実装が必要であることを示します。

4

std::string::find(*)のセマンティクスは、std::findのセマンティクスとはまったく異なります。アルゴリズムの場合、それはstd::stringに適用すると、の文字がXの位置を見つけることになる場合、コンテナ内の要素を見つけるでしょう。(単一charTかかり一の変形除く)

メンバ関数std::string::findは、異なる目的を持って、彼らは、ストリング(すなわち、値の配列ではなく、単一の値)を求めます。

次の質問は、std::findを呼び出すだけのときに、charTがかかる1つのオーバーロードが存在する理由です。 Andyが答えたところで、STLと文字列ライブラリの実装が別々に行われました。イテレータは、std::stringコンポーネントに追加されました。イテレータがstd::stringに追加された時点で、このオーバーロードはすでに存在していましたが、セマンティクスはstd::findとは少し異なり、イテレータの代わりに、の位置 。これは、他のものに関して実装することができないことを意味するものではなく、そのコードだけがより複雑になることを意味する。私と一緒に

(*)クマ...それはstd::basic_string<>

関連する問題