Skip to content

2014 08 19 스트림 반복자, 삽입 반복자, 이동 반복자

krikit edited this page Nov 26, 2014 · 1 revision

스트림 반복자

출력 스트림 반복자를 이용하면 STL 컨테이너의 내용을 반복문을 통해 출력하지 않고도 간단하게 copy 함수를 이용해 출력할 수 있습니다.

#include <list>
#include <iostream>

int main(int argc, char** argv) {
  std::list<int> ints;
  for (int i = 0; i < 10; ++i) {
    ints.push_back(i);
  }
  std::copy(ints.begin(), ints.end(), std::ostream_iterator<int>(std::cout, " "));
  return 0;
}

삽입 반복자

std::copy 함수는 컨테이너를 복사할 때 항목을 삽입하는 것이 아니라 기존에 할당된 메모리 영역에 덮어쓰기를 수행합니다. 따라서, source 반복자의 갯수 이상으로 target 반복자에 메모리가 이미 할당되어 있어야만 합니다.

#include <vector>
#include <iostream>

int main(int argc, char** argv) {
  std::vector<int> src;
  for (int i = 0; i < 10; ++i) {
    src.push_back(i);
  }
  std::vector<int> trg(10, -1);
  std::copy(src.begin(), src.end(), trg.begin());
  std::copy(trg.begin(), trg.end(), std::ostream_iterator<int>(std::cout, " "));
  return 0;
}

그런데, 입력 반복자 back_insert_iterator를 사용하면 메모리를 미리 할당하지 않고도 copy 함수를 사용할 수 있습니다.

#include <vector>
#include <iostream>

int main(int argc, char** argv) {
  std::vector<int> src;
  for (int i = 0; i < 10; ++i) {
    src.push_back(i);
  }
  std::vector<int> trg(10, -1);
  std::copy(src.begin(), src.end(), trg.begin());

  std::back_insert_iterator<std::vector<int> > inserter(trg);
  std::copy(src.begin(), src.end(), inserter);

  // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
  std::copy(trg.begin(), trg.end(), std::ostream_iterator<int>(std::cout, " "));
  return 0;
}

back_inserter 함수를 사용하면 좀더 편리하게 삽입 반복자를 생성할 수 있습니다.

// std::back_insert_iterator<std::vector<int> > inserter(trg);
std::copy(src.begin(), src.end(), std::back_inserter(trg));

이동 반복자

C++11에는 move 시맨틱이 도입됨에 따라 이동 반복자 move_iterator도 제공됩니다. 이러한 반복자를 생성하기위한 make_move_iterator 편의 함수도 제공됩니다.

#include <vector>
#include <iostream>

class MyClass {
 public:
  MyClass() {
    std::cout << "default constructor" << std::endl;
  }

  MyClass(const MyClass& that) {
    std::cout << "copy constructor" << std::endl;
  }

  MyClass(MyClass&& that) {
    std::cout << "move constructor" << std::endl;
  }

  MyClass& operator=(const MyClass& rhs) {
    std::cout << "copy assignment operator" << std::endl;
    return *this;
  }

  MyClass& operator=(MyClass&& rhs) {
    std::cout << "move assignment operator" << std::endl;
    return *this;
  }
};

int main(int argc, char** argv) {
  std::vector<MyClass> src;
  for (int i = 0; i < 2; ++i) {
    src.push_back(MyClass());
    // default constructor
    // move constructor
  }

  std::vector<MyClass> trg1(src.begin(), src.end());
  // copy constructor
  // copy constructor

  std::vector<MyClass> trg2(std::make_move_iterator(src.begin()), std::make_move_iterator(src.end()));
  // move constructor
  // move constructor

  return 0;
}
Clone this wiki locally