1. 導入
C++でプログラムを書いている際、別のコンテナの要素をコピーしたり、アルゴリズムの結果を動的にコンテナに追加したい場面はよくあります。しかし、あらかじめサイズが決まっていないコンテナに対して値を代入しようとすると、領域外アクセスなどのバグを引き起こすリスクがあります。今回紹介する「std::inserter」は、こうした課題を解決し、コンテナの末尾や特定の位置に「挿入」し続けるための強力なツールです。
2. 基礎知識
通常、std::copyなどのアルゴリズムは、指定されたイテレータが指す要素を「上書き」します。しかし、std::inserter(挿入イテレータ)を使うと、代入演算子(=)が呼ばれた際に、内部でコンテナの「insert」メソッドが自動的に呼び出されるようになります。これにより、コンテナのサイズを気にすることなく、要素を次々と追加できるようになるのです。
3. 実装/解決策
std::inserterを使用するには、ヘッダーファイル「iterator」をインクルードする必要があります。
基本的な使い方は、第一引数に「対象のコンテナ」、第二引数に「挿入を開始したい位置を示すイテレータ」を渡すだけです。これだけで、後は通常の代入操作を行うたびに、コンテナ内に新しい要素が挿入され続けます。
4. サンプルプログラム
以下のコードは、std::vectorの途中に別のデータを挿入する例です。そのままコンパイルして動作を確認してみてください。
include
include
include
include
int main() {
// 元となるコンテナ
std::vector
// 挿入したいデータ
std::vector
// vecの2番目の位置(値2の後)に、addの要素を全て挿入する
// std::inserterは、指定位置に次々とinsertを呼び出し続ける
std::copy(add.begin(), add.end(), std::inserter(vec, vec.begin() + 2));
// 結果の出力
for (int n : vec) {
std::cout << n << " ";
}
// 出力結果: 1 2 3 4 5 6 7
return 0;
}
5. 応用・注意点
注意点として、std::inserterを使用する対象のコンテナは「insertメンバ関数」を持っている必要があります。std::vectorやstd::list、std::setなどは問題ありませんが、固定サイズの配列などは対象外です。
また、頻繁に先頭や中間に挿入を行う場合、std::vectorでは要素の再配置(コピー移動)が発生するため、計算量が増大します。大量のデータを中間に挿入し続けるようなケースでは、std::listのような、挿入コストが一定のコンテナを選択するのが現場での定石です。適材適所のコンテナ選びと組み合わせることで、パフォーマンスを最大限に引き出すことができます。

コメント