Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 출력 반복자(Output Iterator) 완벽 정리: inserter와 ostream_iterator

이번 글에서는 C++의 출력 반복자(Output Iterator)가 무엇인지, 그리고 어떤 특성을 가지는지 살펴보겠습니다. 출력 반복자는 컨테이너에 값을 쓰기 위한 특수한 목적의 반복자로, 다음과 같은 중요한 속성들을 가집니다.

출력 반복자의 주요 특징

  • 출력 반복자는 컨테이너의 값을 수정(쓰기)하는 데 사용됩니다.
  • 이 반복자를 통해서는 컨테이너에서 데이터를 읽을 수 없습니다.
  • 단방향(One-Way)이며 쓰기 전용(Write-only) 반복자입니다.
  • 증가(++)는 가능하지만, 감소(--)는 할 수 없습니다.
  • 출력 반복자는 두 가지 하위 유형으로 나뉩니다. 바로 삽입 반복자(Insert Iterator)ostream 반복자(ostream iterator)입니다.

삽입 반복자(Insert Iterator)

삽입 반복자는 컨테이너 내부에 새로운 요소를 삽입할 때 사용합니다. 이 반복자에 대입 연산자(=)를 사용하면 현재 위치에 새 요소가 삽입되며, 기존 요소를 덮어쓰지 않고 뒤로 밀어냅니다. 삽입 반복자의 기본 문법은 다음과 같습니다.

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

삽입 반복자는 두 개의 매개변수를 받습니다.

  • x: 반복자가 동작할 대상 컨테이너입니다.
  • 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

위 예제에서 inserter(vec1, it)는 vec1의 5번째 위치부터 vec2의 모든 요소를 삽입합니다. 결과를 보면 기존 요소들이 덮어써지지 않고 뒤로 밀려난 것을 확인할 수 있습니다.

ostream 반복자(ostream Iterator)

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이 처리할 수 있는 문자 타입입니다.
  • 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,

두 번째 인자로 전달된 ","는 각 요소가 출력될 때마다 구분자(delimiter)로 붙는 문자열입니다.

예제 코드 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,

정리

C++의 출력 반복자는 컨테이너나 스트림에 데이터를 쓰기만 하는 단방향 반복자입니다. inserter를 활용하면 기존 요소를 덮어쓰지 않고 안전하게 삽입할 수 있고, ostream_iterator를 활용하면 copy 같은 STL 알고리즘과 결합해 출력 코드를 훨씬 간결하게 작성할 수 있습니다. 읽기가 필요 없는 순수 출력 상황이라면 출력 반복자를 적극적으로 활용해 보시기 바랍니다.