ベクターに挿入するためのオーバーロードがいくつかあり、そのうちのいくつかはコンストラクター用に複製されています。これらのオーバーロードのうち 2 つは、ベクトル要素が整数型の場合に競合します。
iterator insert( const_iterator pos, size_type count, const T& value );
template< class InputIt >
iterator insert( const_iterator pos, InputIt first, InputIt last );
vector<int>
と callがある場合vec.insert(vec.bgein(), 5, 4)
、値 4 の 5 倍を挿入することを意味していることは間違いありませInputIt
んint
。
この問題とその他の振る舞いの問題を解決するために、標準ライブラリの実装者は、いくつかの特性と一連のタグ クラスを発明しました。特性は、Karthik T が回答で述べたように、3 つの異なるタグを与えるテンプレート メタ関数です。
_Int_iterator_tag
InputIt
整数型の場合
forward_iterator_tag
ifInputIt
は前方反復子 (ランダム アクセス反復子を含む) です。
input_iterator_tag
ifInputIt
は前方反復子ではない反復子型です
_M_range_insert
次に、さまざまなタグタイプを追加のパラメーターとして取り、それぞれが正しいことを行う、のオーバーロードの束を取得します。つまり、
- Int-Tag のオーバーロードは、テンプレート化されていない最初のオーバーロード
insert
(またはその実装)にリダイレクトされます。
- 前方イテレータのオーバーロードは
reserve(std::distance(first,last))
、その後、イテレータ範囲から要素を呼び出してコピーします
- 単純な入力反復子のオーバーロードは要素をコピーするだけで、複数の再割り当てが発生する可能性があります。
reserve
入力イテレータは 1 回しか評価できないため (istream イテレータなど)、 を呼び出すことはできません。
テンプレート化された挿入メソッドは、概念的に次のようになります。
template< class InputIt >
iterator insert( const_iterator pos, InputIt first, InputIt last )
{
return _M_range_insert(pos, first, last, InsertIteratorTraits<InputIt>::tag_type());
}