C ++のSTLライブラリはどのようにしてタイプの区別を実現しますか

1.問題の背景

一般的なテンプレートクラスを作成することもあります。実装プロセスでは、テンプレートパラメータのタイプが必要であり、タイプに応じて対応するアルゴリズム操作を実行します。たとえば、STLライブラリのイテレータオフセットアルゴリズムツールアドバンスは、イテレータを指定された距離だけ移動し、そのテンプレート関数のシグネチャは次のとおりです。

template<typename IterT, typename DistT>
void advance(IterT& iter, DistT d);

STLライブラリのイテレータの種類について説明します。入力、出力、転送、双方向、ランダムアクセスの5種類のイテレータがあります。これらのイテレータのステッピング方法、つまり操作アルゴリズムは異なります。

1.入力タイプのイテレータ(入力):一度に1つずつ順方向に要素を読み取り、この順序で要素値を1つずつ返すことができます。クライアントは、参照するオブジェクトの読み取りのみが可能であり、書き込みはできず、読み取りは1回のみです。つまり、読み取り操作専用に作成されたイテレータです。

2.出力型イテレータ(出力):入力イテレータとは異なり、前進することしかできず、クライアントは参照するものを1回だけ書き込むことができます。つまり、書き込み操作専用に作成されたイテレータです。

3.順方向反復子(順方向):正しい間隔で読み取りおよび書き込み操作を実行できます。入力反復子と出力反復子の特性に加えて、要素を単一のステップで順方向に反復する機能があります。

4.双方向:Forward Iteratorに基づいて、要素を1つのステップで逆方向に反復する機能を提供します。

5.ランダムアクセス:上記のイテレータのすべての機能を備えており、ポインタのような算術計算を実行できます。

Advanceは、これらの種類のイテレータオフセット操作を実装したいと考えていますが、これらのイテレータタイプをどのように認識しますか?結局のところ、テンプレートパラメータの観点からは、IterTがどのイテレータタイプであるかを特定することは不可能です。では、STLライブラリはどのようにそれを行うのでしょうか?

2.タグ(タグ)を入力します

特定のものを識別するために、私たちの方法の1つは、他のものとは異なるマークを付けることです。C ++は、一意のクラス属性を持つstruct Dummy {};などの空の型をサポートします。したがって、空の型機能を使用してis-a機能を継承すると、特定のクラスに一意のラベルを付けることができます。この種類のラベルはラベル構造と呼ばれ、IDIDとして理解できます。これらのタグで構成されるシステムは、型システムと呼ぶことができます。

C ++ STLは、上記の5つのイテレータータイプに対応する5つのタイプのタグを提供します。

struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : input_iterator_tag {};
struct bidirectional_iterator_tag : forward_iterator_tag {};
struct random_access_iterator_tag : bidirectional_iterator_tag {};

したがって、C ++が提供する型抽出(特性)テクノロジを使用して、これら5つのイテレータ型を識別し、対応するイテレータオフセットアルゴリズムをさまざまな型に従って実装できます。

おすすめ

転載: blog.csdn.net/xunye_dream/article/details/114778113