C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++の出力イテレータ(Output Iterator)とは?使い方を徹底解説

本記事では、C++における出力イテレータ(Output Iterator)について詳しく解説します。出力イテレータにはいくつかの重要な特性があり、それらは以下のようにまとめられます。

  • コンテナ内の値を変更(書き込み)するために使用される。
  • この種のイテレータでは、コンテナからデータを読み取ることはできない
  • 一方向・書き込み専用のイテレータである。
  • インクリメント(前進)は可能だが、デクリメント(後退)はできない。
  • 出力イテレータには2つの種類がある。挿入イテレータ(Insert Iterator)ostreamイテレータである。

挿入イテレータ(Insert Iterator)とは

挿入イテレータは、コンテナ内に新しい要素を挿入するために使用されます。この種のイテレータに対して代入演算子を使用すると、現在の位置に新しい要素が挿入されます。既存の要素が上書きされるのではなく、指定位置に要素が「差し込まれる」点が特徴です。

挿入イテレータの構文は以下の通りです。

template<class Container, class Iterator>
insert_iterator<container> inserter(Container &x, Iterator it);

この関数は2つの引数を受け取ります。第1引数の x は、イテレータが操作対象とするコンテナです。第2引数の it は、挿入位置を指すイテレータオブジェクトです。

サンプルコード

#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> vec1, vec2;
    for (int i = 1; i <= 10; i++) { // ベクトルに要素を挿入
        vec1.push_back(i);
        vec2.push_back(i + 3);
    }
    vector<int>::iterator it = vec1.begin(); // vec1に対して動作するイテレータ
    advance(it, 5); // イテレータを5つ先へ進める
    copy(vec2.begin(), vec2.end(), inserter(vec1, it));
    cout << "vec1の要素 :";
    for (it = vec1.begin(); it != vec1.end(); ++it)
        cout << ' ' << *it;
    cout << endl;
    return 0;
}

実行結果

vec1の要素 : 1 2 3 4 5 4 5 6 7 8 9 10 11 12 13 6 7 8 9 10

この例では、vec1 の5番目の位置に vec2 の全要素(4〜13)が挿入されていることがわかります。元の要素6以降は後ろにずらされ、失われることなく保持されています。

ostreamイテレータとは

ostreamイテレータは、cout のような出力ストリームへの書き込みを行うために使用されます。basic_ostream オブジェクトを使って生成でき、この種のイテレータに代入演算子を使用すると、出力ストリームに新しい要素が出力されます。

構文は以下の通りです。

template<class T, class charT = char, class traits = char_traits<charT>>
class ostream_iterator;

ostreamイテレータクラスの主なメンバ関数は以下の通りです。

ostream_iterator<T, charT, traits>& operator=(const T& value);
ostream_iterator<T, charT, traits>& operator*();
ostream_iterator<T, charT, traits>& operator++();
ostream_iterator<T, charT, traits>& operator++(int);

テンプレートパラメータの意味は次の通りです。

  • T: 挿入される要素の型。
  • charT: ostreamが扱える文字の型(デフォルトは char)。
  • traits: ストリームが扱う文字特性(character traits)。

サンプルコード1:copyアルゴリズムとの組み合わせ

#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> v;
    for (int i = 1; i <= 10; i++)
        v.push_back(i * i); // 平方数を計算して挿入
    ostream_iterator<int> out(cout, ",");
    copy(v.begin(), v.end(), out);
    return 0;
}

実行結果

1,4,9,16,25,36,49,64,81,100,

この例では、ostream_iterator の第2引数として区切り文字 "," を指定しているため、各要素の後にカンマが出力されます。

サンプルコード2:直接代入による出力

#include <iostream>
#include <iterator>
using namespace std;

int main() {
    ostream_iterator<int> os_out(cout, ",");
    *os_out = 10;
    os_out++; // 次の位置へ進む
    *os_out = 20;
    os_out++;
    *os_out = 30;
    return 0;
}

実行結果

10,20,30,

このように、ostreamイテレータは通常のイテレータと同じように * 演算子や ++ 演算子を使って操作でき、代入のたびに出力ストリームへ値が書き込まれます。STLのアルゴリズム(copy など)と組み合わせることで、コンテナの内容を簡潔に出力できる便利なツールです。

  1. 【C++入門】ストリームクラスの階層構造と入出力の基本を徹底解説

    C++におけるストリームとは C++における「ストリーム」とは、プログラムと入出力(I/O)デバイスの間でやり取りされる文字データの流れを指します。 ストリームクラスは、ファイルや入出力デバイスに対する入出力操作を扱うためのクラス群です。それぞれのクラスが固有の役割を持っており、プログラムの入力・出力を効率的に処理できます。 C++のすべてのストリームクラスは、iostreamライブラリにまとめられています。 まずは、ストリームクラスの階層構造を見てみましょう。 iostreamライブラリの主要クラス iosクラス iosクラスは、すべてのストリームクラスの基底クラス(ベースクラス)です。

  2. C++で作るマトリックス風・文字が降り注ぐエフェクトの実装方法

    映画『マトリックス』などでおなじみの、緑色の文字が画面を流れ落ちるあの演出。実はC++の標準ライブラリだけでも、コンソール上に簡単に再現できます。この記事では、乱数・スレッド・スリープ処理を組み合わせて、マトリックス風の「文字が降り注ぐエフェクト」を実装する方法を解説します。 実装のポイント この演出を実現するには、次の3つの要素を押さえておく必要があります。 マトリックスの幅を定義する … 1行に表示する最大桁数(画面幅)を決めます。 文字の間隔をランダムにする … 隣り合う文字どうしの隙間は一定である必要はありません。ランダム性を持たせることで、自然でノイズ感のある演出になります。 表