STL は、OOP と従来のプログラミングの両方で使用できる多数のテンプレート クラスと関数を提供します。 STL の約 50 個のアルゴリズムはすべて完全に汎用的であり、特定のデータ型に依存しません。次のサブセクションでは、3 つの基本的な STL コンポーネントについて説明します。 1) イテレータはコンテナ内のオブジェクトにアクセスする方法を提供します。たとえば、反復子のペアを使用して、リストまたはベクトル内のオブジェクトの範囲を指定できます。イテレータはポインタのようなものです。実際、C++ ポインタもイテレータの一種です。ただし、イテレータは、operator*() やその他のポインタのような演算子のメソッドを定義するクラスのオブジェクトになることもできます。 2) コンテナは、テンプレート クラスのメソッドとして提供されるリスト、ベクター、デキューなどのデータ構造です。コンテナ内のデータにアクセスするには、コンテナ クラスによってエクスポートされた反復子を使用します。 3) アルゴリズムは、コンテナ内のデータを操作するために使用されるテンプレート関数です。たとえば、STL はベクトル内のデータをソートするために sort() を使用し、リスト内のオブジェクトを検索するために find() を使用します。関数自体は、操作するデータの構造や型に依存しないため、単純な配列から非常に複雑なコンテナーまで、あらゆるデータ構造で使用できます。 関数と関数オブジェクト STL では、関数はアルゴリズムと呼ばれ、標準の C ライブラリ関数よりも汎用的です。 STL アルゴリズムは、operator() 関数をオーバーロードすることによってテンプレート クラスまたはテンプレート関数として実装されます。これらのクラスは、コンテナー内のデータに対してさまざまな操作を実行する関数オブジェクトを作成するために使用されます。次のセクションでは、関数と関数オブジェクトの使用方法について説明します。 関数とアサーション 多くの場合、コンテナ内のデータに対してユーザー定義の操作を実行する必要があります。たとえば、コンテナー内のすべてのオブジェクトを反復処理して、独自の関数にコールバックできるようにする STL アルゴリズムが必要な場合があります。例えば
いわゆるアサーション関数は、bool 値を返す関数です。 関数オブジェクト STL アルゴリズムにコールバック関数を渡すだけでなく、より複雑な操作を実行するためにクラス オブジェクトを渡す必要がある場合もあります。このようなオブジェクトは関数オブジェクトと呼ばれます。実際、関数オブジェクトはクラスですが、コールバック関数と同じようにコールバックできます。たとえば、関数オブジェクトは、for_each() または find_if() 関数によって呼び出されるたびに統計を保持できます。関数オブジェクトは、operator()() をオーバーロードすることによって実装されます。 TanyClass が operator()() を定義している場合は、次のように使用できます。
STL はいくつかの関数オブジェクトを定義します。これらはテンプレートなので、long などの C/C++ ネイティブ データ型を含むあらゆる型に使用できます。一部の関数オブジェクトには、plus() や multiplies() など、その目的を明確に示す名前が付けられています。同様のメソッド greater() と less-equal() は、2 つの値を比較するために使用されます。 知らせ ANSI C++ の一部のバージョンでは times() 関数オブジェクトが定義されていますが、GNU C++ では multiplies() という名前が付けられています。使用時にはヘッダー ファイル < functional> を含める必要があります。 関数オブジェクトの便利な応用例は、accumulate() アルゴリズムです。この関数はコンテナ内のすべての値の合計を計算します。このような値は単純な型である必要はなく、operator+() をオーバーロードすることでクラス オブジェクトにすることもできることに注意してください。 リスト8. accum.cpp
コンパイル出力は次のようになります。
『関数オブジェクトを使用するaccumulate()の使用法に注意してください。 accelerate() は内部的にコンテナ内の各オブジェクトと 3 番目の引数を multiplies 関数オブジェクトへの引数として渡し、multiplies(1,v) は積を計算します。 VC でのこれらのテンプレートのソース コードは次のとおりです。
はじめに: STL がどのように実装されているかを深く理解したい場合、最も良い方法は、簡単なプログラムを書いて、プログラムに含まれるテンプレート ソース コードをコピーし、少し整理してみることです。そうすれば、理解できるようになります。したがって、「STL ソースコード分析」のような本を購入する必要はありません。これらの本は時間の無駄になる可能性があります。 』 (1)ジェネレータ関数オブジェクト 関数オブジェクトの便利なクラスの 1 つは「ジェネレーター」です。このような関数には独自のメモリがあり、以前の呼び出しの値を記憶することができます。たとえば、乱数生成関数。 通常の C プログラマーは、静的変数またはグローバル変数を使用して、前回の呼び出しの結果を「記憶」します。しかし、これを行うことの欠点は、関数をそのデータから分離できないことです。もう 1 つの欠点は、スレッドの安全性を確保するために TLS が必要になることです。明らかに、クラスを使用して「メモリ」の一部をカプセル化する方が安全で信頼性が高くなります。例を見てみましょう: リスト9. randfunc.cpp
コンパイルと実行結果は次のとおりです。
まず、次のステートメントでオブジェクトを宣言します。
ここでは、STL 単項関数テンプレートを使用して変数 ptr_RandInt を定義し、関数 RandInt() へのアドレスを初期化します。単眼関数は 1 つの引数を受け取り、値を返します。これで、random_shuffle() は次のように呼び出すことができます。
この例では、ジェネレーターは単に rand() 関数を呼び出します。 定数参照に関するちょっとした問題 (翻訳なし、VC の例の const を削除) #p# (2)ジェネレータ関数クラスオブジェクト 次の例は、ジェネレータ関数クラス オブジェクトの使用を示しています。 リスト 10. fiborand.cpp
コンパイルして実行した結果の出力は次のようになります。
このプログラムは rand_shuffle をまったく異なる方法で使用します。フィボナッチ ジェネレーターは、以前の「使用」の結果を記憶するクラスにカプセル化されます。この例では、クラス FiboRand は配列と 2 つのインデックス変数 I と j を管理します。 FiboRand クラスは unary_function() テンプレートから継承します。
Arg はユーザー定義のデータ型です。このクラスは、コンストラクターと operator() 関数の 2 つのメンバー関数も定義します。これにより、random_shuffle() アルゴリズムは FiboRand オブジェクトを関数のように「呼び出す」ことができます。 #p# (3)バインダー関数オブジェクト バインダーは、別の関数オブジェクト f() とパラメーター値 V を使用して関数オブジェクトを作成します。バインドされた関数オブジェクトはバイナリ関数である必要があります。つまり、2 つのパラメーター A と B を持ちます。 STL のバインダーは次のとおりです。
以下にいくつか例を挙げます。 リスト 11. バインダー.cpp
アルゴリズム count_if() は、特定の条件を満たす要素の数をカウントします。 これは、関数オブジェクトとパラメータをオブジェクトにバンドルし、そのオブジェクトをアルゴリズムの 3 番目の引数として渡すことによって行われます。 この表現に注目してください:
この式は、greater<int>() とパラメータ値 8 を関数オブジェクトにバンドルします。 bind1st() が使用されているため、この関数は次の式を計算することと同等になります。 8 > ク 式内の q はコンテナ内のオブジェクトです。したがって、完全な表現は
サイズが 8 以下のすべてのオブジェクトの数を数えます。 (4)関数オブジェクトの否定 否定関数オブジェクトは、別の関数オブジェクトから作成されるオブジェクトです。元の関数が true を返す場合、否定関数オブジェクトは false を返します。否定関数オブジェクトには、not1() と not2() の 2 つがあります。 not1() は単眼関数オブジェクトを受け入れ、not2() は両眼関数オブジェクトを受け入れます。負の関数オブジェクトはバインダーでよく使用されます。たとえば、前のセクションでは、bind1nd を使用して q <= 8 の値を検索しました。
q>8 のオブジェクトを検索する場合は、bind2st を使用します。次のように書くことができます:
bind1nd は単項関数を返すため、not1 を使用する必要があります。 概要: 標準テンプレートライブラリ (STL) の使用 多くのプログラマーは依然として標準の C 関数を使用していますが、それはメルセデスを探すのにロバに乗るようなものです。最終的にはそこにたどり着くでしょうが、多くの時間を無駄にしてしまうことになります。 ただし、標準の C 関数 (フォーマットされた出力に sprintf() を使用するなど) を使用すると便利な場合もあります。ただし、C 関数はエラーを報告するために例外メカニズムを使用しないため、新しいデータ型の処理には適していません。さらに、標準の C 関数ではメモリ割り当て技術が使用されることが多く、経験の浅いプログラマーは簡単にバグを記述する可能性があります。 。 C++ 標準ライブラリは、データ セットを処理するためのより安全で柔軟な方法を提供します。 STL はもともと、HP Labs の Alexander Stepanov と Meng Lee によって開発されました。最近、C++ 標準委員会は STL を採用しましたが、実装ごとに詳細はまだ異なります。 STL の 2 つの主な特徴は、データ構造とアルゴリズムの分離と非オブジェクト指向性です。オブジェクトへのアクセスは、ポインタのような反復子を通じて実現されます。コンテナーは、リンク リストやベクターのようなデータ構造であり、テンプレート形式で提供されます。アルゴリズムは、コンテナー内のデータを操作するために使用される関数テンプレートです。 STL はテンプレートに基づいているため、あらゆるデータ型と構造に使用できます。 【編集者のおすすめ】
|
<<: C++開発におけるデータ構造とアルゴリズムの分離についての簡単な説明
>>: MySQLインデックスの背後にあるデータ構造とアルゴリズムの原理
現時点で最もホットなコンセプトは何かと聞かれれば、それは人工知能であるに違いないと私は思います。 A...
過去10年間、テクノロジーおよび自動車の専門家は、人間の運転手による積極的な監視や入力なしに公道を走...
皆さん、OpenAI は誰でも開発できるカスタム GPT をリリースしたばかりです。そして、中国の大...
医用画像診断における人工知能(AI)の応用は大きな進歩を遂げました。しかし、厳密なテストがなければ、...
機械学習では、ML モデルの作成とパッケージ化を支援する ML 開発プラットフォームの概要を説明しま...
[[377773]]人工知能は、業界団体によって大々的に宣伝され、推進されている用語の 1 つになっ...
[[226709]]ビッグデータ概要翻訳者:Fu Yiyang、Ding Hui、Aileen A...
4G と 5G の世界的な展開は商用サービスの進歩よりも速く、6G は 2030 年までに登場する...
[[437247]]この記事はAI新メディアQuantum Bit(公開アカウントID:QbitA...
この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...
Covid-19パンデミックの発生に伴い、あらゆる業界の企業が先進技術を活用して、私たちの働き方や生...
科学技術の継続的な発展に伴い、人工知能は徐々に科学技術分野の主な研究方向になってきました。 「ロボッ...