블로그는 귀차니즘

First Sensation
  • 공지
  • 지역로그
  • 태그
  • 방명록

std::copy - ostream_iterator 사용법의 이유

Language 2008/03/06 23:55 귀차니스트
  가장 맨 처음 어떤 STL Container에 들어있는 값들을 출력을 하려고 하면 흔히 사용하는 방법이 해당 Container에 속해있는 Iterator로 전진반복을 하면서 출력하는 것입니다. 보통 아래와 같은 코드가 되죠.

IterTest.cpp (Language : cpp)
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4.  
  5. int main( int argc, char **argv )
  6. {
  7.     std::vector< int > abc;
  8.     abc.push_back( 1 );
  9.     abc.push_back( 2 );
  10.     abc.push_back( 3 );
  11.     abc.push_back( 4 );
  12.     abc.push_back( 5 );
  13.  
  14.     for( std::vector< int >::const_iterator Iter = abc.begin(); Iter != abc.end(); ++Iter ) {
  15.        
  16.         std::cout << *Iter << std::endl;
  17.     }
  18.  
  19.     return 0;
  20. }

  그런데 알고보면 이게 오히려 가독성을 떨어트릴 수도 있습니다. 실제로 for 구문에 대하여 모든 것을 인식해야 하고 조건, 증가식등을 알아야 하기 때문이죠. 그에 반해 좋은 방법이 하나 존재합니다. 바로 std::copy 알고리즘을 사용하는 것인데요. 사용법은 바로 아래와 같습니다.

CopyTest.cpp (Language : cpp)
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4.  
  5. int main( int argc, char **argv )
  6. {
  7.     std::vector< int > abc;
  8.     abc.push_back( 1 );
  9.     abc.push_back( 2 );
  10.     abc.push_back( 3 );
  11.     abc.push_back( 4 );
  12.     abc.push_back( 5 );
  13.  
  14.     std::copy( abc.begin(), abc.end(), std::ostream_iterator< int >( std::cout, "\r\n" ) );
  15.  
  16.     return 0;
  17. }

  이 것은 std::copy가 begin 에서 부터 end 까지 ( , ] 구간을 std::ostream_iterator 함수 객체에 대하여 = assign 연산을 수행 시켜주는 알고리즘이기 때문에 가능한 것이죠. 물론 함수객체가 아닌 함수 포인터도 가능합니다. 그런데 std::ostream_iterator 가 왜 이렇게 되는지 궁금하지 않나요? iterator 헤더 안에 들어가 검색을 해보니 다음과 같은 소스 부분이 존재하더군요.

ostream_iterator.cpp (Language : cpp)
  1. template<class _Ty,
  2.     class _Elem = char,
  3.     class _Traits = char_traits<_Elem> >
  4.     class ostream_iterator
  5.         : public _Outit
  6.     {   // wrap _Ty inserts to output stream as output iterator
  7. public:
  8.     typedef _Elem char_type;
  9.     typedef _Traits traits_type;
  10.     typedef basic_ostream<_Elem, _Traits> ostream_type;
  11.  
  12. #if _SECURE_SCL
  13.     typedef _Range_checked_iterator_tag _Checked_iterator_category;
  14. #endif
  15.  
  16.     ostream_iterator(ostream_type& _Ostr,
  17.         const _Elem *_Delim = 0)
  18.         : _Myostr(&_Ostr), _Mydelim(_Delim)
  19.         {   // construct from output stream and delimiter
  20.         }
  21.  
  22.     ostream_iterator<_Ty, _Elem, _Traits>& operator=(const _Ty& _Val)
  23.         {   // insert value into output stream, followed by delimiter
  24.         *_Myostr << _Val;
  25.         if (_Mydelim != 0)
  26.             *_Myostr << _Mydelim;
  27.  
  28. .
  29. .
  30. .
  31. 생략

  바로 선언시 전달 받은 ostream_type을 함수객체의 지역성에 의하여 보관하고 있는 상황에서 해당 객체에 대한 = operator에 의한 Assign 문장이 실행되면 *Myostr 에 << 연산으로 값을 넣게 되는 것입니다. 이 것은 미리 basic_ostream 객체( 예를 들면 cout )에서 미리 정의된 객체에 대하여 << 연산자가 미리 정의 되어있기 때문에 가능한 것이죠. 만약 미리 정의 되지 않았다면 << 연산에 대하여 컴파일 에러가 발생합니다. 이 것 뿐만이 아니라 iterator 종류는 무척 많습니다.

back_insert_iterator.cpp (Language : cpp)
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <vector>
  4.  
  5. int main( int argc, char **argv )
  6. {
  7.     std::vector< int > abc;
  8.     std::vector< int > def;
  9.     abc.push_back( 1 );
  10.     abc.push_back( 2 );
  11.     abc.push_back( 3 );
  12.     abc.push_back( 4 );
  13.     abc.push_back( 5 );
  14.  
  15.     std::copy( abc.begin(), abc.end(), std::back_insert_iterator< std::vector< int > >( def ) );
  16.  
  17.     return 0;
  18. }

  예로써 위의 back_insert_iterator 와 같은 iterator 를 들수 있습니다. 물론 이보다는 std::insert 알고리즘이 더 좋습니다. back_insert_iterator는 해당 객체에 대하여 push_back 함수를 값을 인자로 호출해주는 것을 대행하게 되죠. 이렇게 보니 이전 for 루프에 대하여 출력하기 전 보다 훨씬 가독성도 높아지고 iterator 를 재정의 하면 새로운 부분들도 확장시킬 수 있을것 같다는 생각이 들지 않나요?? Iterator 를 해당 필요상황에 맞게 잘 사용하면 무척 좋겠다는 생각이 듭니다.
크리에이티브 커먼즈 라이센스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

"Language" 분류의 다른 글

boost::spirit - Parser 라이브러리 (0)2008/04/23
std::ostreambuf_iterator, std::istreambuf_iterator의 이유 (1)2008/04/16
std::auto_ptr - Smart Pointer 이지만?? (1)2008/04/13
C# Application - Main 에서 Try-Catch 오작동 해결하는 방법 (4)2008/04/07
Boost 1.35 - 워크샵 뒤의 포스팅 (2)2008/04/03
2008/03/06 23:55 2008/03/06 23:55
TAG Iterator, std::copy, 반복자
받은 트랙백이 없고, 댓글이 없습니다.

트랙백 주소 :: http://www.filewiki.net/tc/trackback/26

댓글을 달아 주세요

◀ 이전페이지 1 다음페이지 ▶

블로그 이미지
First Sensation 귀차니스트
rss
  • 관리자
  • 글쓰기

카테고리

  • 전체 (111)
    • Computer (3)
    • Language (14)
    • Reverse Engineering (1)
    • Algorithm (9)
    • TopCoder (3)
    • Library (2)
    • Programming (20)
    • Programming Tip (9)
    • PSP-Programming (10)
    • Program (5)
    • Small Talk (31)
    • Document (4)

최근에 올라온 글

  • Gradient에 대한 정리.
  • Gradient 작성중에 있습.... (3)
  • 게임&인터랙티브 애플리....
  • 한게임 자동테트리스 Ve.... (27)
  • Intel 64 And IA32 Arch.... (2)

최근에 달린 댓글

  • 관리자만 볼 수 있는 댓글입.... 비밀방문자 01/08
  • 글쎄요.. 프로그램이라는게.... 귀차니스트 01/08
  • 관리자만 볼 수 있는 댓글입.... 비밀방문자 01/07
  • 본문에 배포는 하지 않는다고.... 귀차니스트 01/07
  • 다운어덯게 받아요. difl 2008

달력

«   2009/01   »
일 월 화 수 목 금 토
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

링크

  • kkamagui 프로그래밍 세상.
  • 류광의 번역 이야기.
  • 서광열의 프로그래밍 언....
  • 준호씨의 블로그.
  • 최익필의 이름없는 블로그.
  • 위키는 귀차니즘.

최근에 받은 트랙백

  • 궁극의 예외처리. 이름없는 블로그 2008
  • Maximum sum. 티스토리 지점 2008

글 보관함

  • 2009/01 (1)
  • 2008/12 (1)
  • 2008/11 (4)
  • 2008/10 (2)
  • 2008/09 (3)

태그목록

  • 입양
  • System.Xml
  • Ribbon UI
  • Mouse Message
  • 6GB
  • Application.Run
  • priority_queue
  • As 형 변환
  • XHTML
  • smart Pointer
  • \r\n
  • std::copy
  • 갑
  • KDevelop
  • ACM
  • High Precision Event Timer
  • C
  • 개발일지
  • Newline
  • 부트로더
  • FreeType
  • Codegear
  • Develope
  • RCW
  • Parent
  • Pangya
  • 계발
  • 홈브류
  • ACM-ICPC
  • 관악기

지역로그 : 태그 : 방명록 : 관리자 : 글쓰기
귀차니스트’s Blog is powered by Textcube 1.7.5 : Risoluto / Designed by DesignNia.net