블로그는 귀차니즘

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

std::ostreambuf_iterator, std::istreambuf_iterator의 이유

Language 2008/04/16 22:33 귀차니스트
  저도 STL에 있어서 많은 것을 알고 있는 사람이 아니고, 아직 미숙하지만 개중에 입출력과 관련해서 유용한 iterator가 있다는 것을 알아 유용하게 사용하고 있습니다. 제가 사용하는 부분은 std::copy 알고리즘에서 std::ostream_iterator를 이용한 개체 내용의 출력부분입니다. 이를 이용한 코드는 저번에도 포스팅이 되었던 내용입니다. 그런데 이 ostream_iterator, istream_iterator에 대하여 Effective STL에서 한 가지 주제가 존재하여서 그에 대한 내용을 보려고 합니다.

iteratorbuf_iterator.cpp (Language : cpp)
  1. #include <iostream>
  2. #include <algorithm>
  3.  
  4. int main( int argc, char **argv )
  5. {
  6.     std::copy( ( std::istreambuf_iterator< char >( std::cin ) ), std::istreambuf_iterator< char >(), std::ostreambuf_iterator< char >( std::cout ) );
  7.     return 0;
  8. }

  주로 사용은 이렇게 하더군요. 이게 가능한 까닭은 바로 다음과 같은 코드에 있다는 것이 중요합니다.

copy.cpp (Language : cpp)
  1. template<class _InIt, class _OutIt>
  2. inline
  3. _SCL_INSECURE_DEPRECATE
  4. _IF_NOT_CHK(_OutIt) __CLRCALL_OR_CDECL copy(_InIt _First, _InIt _Last, _OutIt _Dest)
  5. {   // copy [_First, _Last) to [_Dest, ...)
  6.     return (_Copy_opt(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest,
  7.         _Iter_random(_First, _Dest), _Ptr_cat(_First, _Dest), _Range_checked_iterator_tag()));
  8. }
istreambuf_iterator.cpp (Language : cpp)
  1. template<class _Elem,
  2.     class _Traits>
  3.     class istreambuf_iterator
  4.         : public iterator<input_iterator_tag,
  5.             _Elem, typename _Traits::off_type, _Elem *, _Elem&>
  6. .
  7. .
  8. .
  9. _Elem operator*() const
  10. {   // return designated value
  11.     if (!_Got)
  12.         ((_Myt *)this)->_Peek();
  13.  
  14.  #if _HAS_ITERATOR_DEBUGGING
  15.     if (_Strbuf == 0)
  16.         _DEBUG_ERROR("istreambuf_iterator is not dereferencable");
  17.  #endif /* _HAS_ITERATOR_DEBUGGING */
  18.  
  19.     return (_Val);
  20. }
ostreambuf_iterator.cpp (Language : cpp)
  1. template<class _Elem,
  2.     class _Traits>
  3.     class ostreambuf_iterator
  4.         : public _Outit
  5. .
  6. .
  7. .
  8. _Myt& operator=(_Elem _Right)
  9. {   // store element and increment
  10.     if (_Strbuf == 0
  11.         || traits_type::eq_int_type(_Traits::eof(),
  12.         _Strbuf->sputc(_Right)))
  13.     _Failed = true;
  14.     return (*this);
  15. }

  Copy 알고리즘에서는 iterator이기 때문에 *연산자를 통하여 값을 읽어오게 되고, ostreambuf_iterator에 = 대입 연산자로 값을 입력하기 때문에 그렇습니다. 실제로 대충 돌아가는 루틴이 눈에 보이시죠?^^. 이 istreambuf_iterator, ostreambuf_iterator와 istream_iterator, ostream_iterator가 다른 점은 기타 점도 있겠지만 출력에 있어서 값을 읽어오고 값을 출력하는 부분이 _Strbuf 를 이용한 직접 액세스 라는 점입니다.

istream_iterator.cpp (Language : cpp)
  1. template<class _Ty,
  2.     class _Elem = char,
  3.     class _Traits = char_traits<_Elem>,
  4.     class _Diff = ptrdiff_t>
  5.     class istream_iterator
  6.         : public iterator<input_iterator_tag, _Ty, _Diff,
  7.             const _Ty *, const _Ty&>
  8. .
  9. .
  10. .
  11. const _Ty& operator*() const
  12. {   // return designated value
  13.  
  14.  #if _HAS_ITERATOR_DEBUGGING
  15.     if (_Myistr == 0)
  16.     {
  17.         _DEBUG_ERROR("istream_iterator is not dereferencable");
  18.         _SCL_SECURE_OUT_OF_RANGE;
  19.     }
  20.  #else
  21.     _SCL_SECURE_VALIDATE_RANGE(_Myistr != 0);
  22.  #endif /* _HAS_ITERATOR_DEBUGGING */
  23.  
  24.     return (_Myval);
  25. }
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. .
  7. .
  8. .
  9. ostream_iterator<_Ty, _Elem, _Traits>& operator=(const _Ty& _Val)
  10. {   // insert value into output stream, followed by delimiter
  11.     *_Myostr << _Val;
  12.     if (_Mydelim != 0)
  13.         *_Myostr << _Mydelim;
  14.  
  15.  #if _HAS_ITERATOR_DEBUGGING
  16.     if (!*_Myostr)
  17.     {
  18.         _DEBUG_ERROR("ostream_iterator is not dereferencable");
  19.         _SCL_SECURE_OUT_OF_RANGE;
  20.     }
  21.  #else
  22.     _SCL_SECURE_VALIDATE_RANGE(*_Myostr != NULL);
  23.  #endif /* _HAS_ITERATOR_DEBUGGING */
  24.  
  25.     return (*this);
  26. }

  buf_iterator와 다른 점은 <<, >> 연산자를 통하냐 통하지 않고 직접 액세스 하느냐에 따라 달렸습니다. 이 점 때문에 buf_iterator와 아닌 것의 속도 차이가 분명 존재하게 됩니다. 그래서 별 다른 문제가 존재하지 않고 buf_iterator로써 가능하다면 이 것을 사용하는 것이 속도상으로 좋다는 말이 여기서 나오는 말 일테구요.
  하지만 장점이 있다면 단점도 존재하겠죠??

Error.cpp (Language : cpp)
  1. #include <iostream>
  2. #include <algorithm>
  3.  
  4. int main( int argc, char **argv )
  5. {
  6.     std::copy( ( std::istreambuf_iterator< char >( std::cin ) ), std::istreambuf_iterator< char >(), std::ostreambuf_iterator< int >( std::cout ) );
  7.     return 0;
  8. }

  이 코드를 실행해 보면 에러가 발생합니다. 그 이유는 바로 rdbuf 개체를 통한 직접 액세스를 std::cout 에서 하기 때문에 그렇습니다. 대충 이러한 오류가 발생하는 까닭은 std::cout이 다음과 같이 정의 되어있기 때문인것 같습니다.

cout.cpp (Language : cpp)
  1. __PURE_APPDOMAIN_GLOBAL extern _CRTDATA2 ostream cout;
ostream.cpp (Language : cpp)
  1. typedef basic_ostream<char, char_traits<char> > ostream;

  위와 같이 정의가 되어있는데 basic_ostream이 int 형으로 됨으로 인하여 생성되는 Class 는  typedef basic_ostream<_Elem, _Traits> ostream_type; 와 같은 형태인데. 이 형태를 int 형 buf_iterator 내부에 존재하는 클래스와 호환이 안되기 때문에 그런 것 같군요.
  정확한 이유는 한 번 제대로 따라가봐야 할 것 같은데, 일단 결론만 얘기하자면 ostream_iterator는 int 형태로 잡아주어도 출력이 가능합니다. 위에 언급한 바와 같이 <<, >> 연산자로써 std::cout << 1; 을 실행하는 것과 동일하게 처리가 된다고 보시면 되니까요.

  buf_iterator 와 아닌 것의 차이를 대충 보았는데, 간단한 몇 자의 타자의 차이임에도 불구하고 속도의 차이가 벌어질 수 있다는 점. 놓칠 수 없다고 생각되지 않나요?^^. 하나하나 살펴보다 보면 모든 부분을 정복할 수 있을 것이라 생각이 드는군요^^;
크리에이티브 커먼즈 라이센스
Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.

"Language" 분류의 다른 글

boost::spirit - Parser 라이브러리 (0)2008/04/23
std::auto_ptr - Smart Pointer 이지만?? (1)2008/04/13
C# Application - Main 에서 Try-Catch 오작동 해결하는 방법 (7)2008/04/07
Boost 1.35 - 워크샵 뒤의 포스팅 (2)2008/04/03
C# Generics - Generics 문법의 사용법 (0)2008/03/21
2008/04/16 22:33 2008/04/16 22:33
TAG C++, istreambuf_iterator, istream_iterator, ostreambuf_iterator, ostream_iterator
받은 트랙백이 없고, 댓글 하나가 달렸습니다.

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

댓글을 달아 주세요

  1. 최익필 2008/07/27 21:16  댓글주소  수정/삭제  댓글쓰기

    트랙백이 가지 않아 댓글로 남겨 둡니다.^^ 입출력 스트림 라이브러리 찾덧 중에 좋은 정보가 있어서 들렸습니다.

    관련글 : http://ikpil.com/552

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

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

카테고리

  • 전체 (118)
    • Computer (3)
    • Language (14)
    • Reverse Engineering (1)
    • Algorithm (9)
    • TopCoder (3)
    • Library (2)
    • Programming (21)
    • Programming Tip (9)
    • PSP-Programming (10)
    • Program (5)
    • Small Talk (33)
    • Document (4)
    • OS Develope (4)

최근에 올라온 글

  • Script Interpreter - b....
  • VirtualHttpServer - 가.... (2)
  • 음.. 여러가지 일이 있.... (2)
  • 어후.. 드디어 인터럽트....
  • Kernel Image에 어이없....

최근에 달린 댓글

  • 헠 ㅋ 다음에도 들러주세용 ㅋㅋ. 귀차니스트 03/09
  • ㅎㅎ RSS로 첨 온 글이네.ㅋ. 당구리 02/22
  • 음.. 한글화 파일 0.5 버젼은.... 귀차니스트 02/22
  • 관리자만 볼 수 있는 댓글입.... 비밀방문자 01/30
  • 어떤 의미이신지 잘 모르겠네.... 귀차니스트 01/23

달력

«   2010/03   »
일 월 화 수 목 금 토
  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 프로그래밍 세상.
  • runner님의 이글루.
  • 당구리의 마굿간.
  • 동우fly.
  • 류광의 번역 이야기.
  • 서광열의 프로그래밍 언....
  • 준호씨의 블로그.
  • 최익필의 이름없는 블로그.
  • 위키는 귀차니즘.

최근에 받은 트랙백

  • 한게임 테트리스 인공지.... 고니's Life 2009
  • ACM 706 (Uva ID) : LCD.... 알고리즘 트레이닝 : Oh... 2009
  • 문제 4 : LCD 디스플레.... 최익필의 이름없는 블로그 2009
  • 궁극의 예외처리. 이름없는 블로그 2008
  • Maximum sum. 티스토리 지점 2008

글 보관함

  • 2010/03 (1)
  • 2010/02 (1)
  • 2010/01 (1)
  • 2009/12 (3)
  • 2009/08 (1)

태그목록

  • 수학
  • ostreambuf_iterator
  • 개발
  • 예외
  • Interface
  • 디자인패턴
  • 관악기
  • HTML 파서
  • Dialog
  • Builder
  • Sector
  • boost::array
  • 디자인
  • 개발일지
  • Secure
  • RCW
  • 전위연산
  • 1.35
  • std::auto_ptr
  • System.Xml
  • iterator_traits
  • RF959
  • ACM-ICPC
  • OS개발
  • ++i
  • 후위연산
  • Image Processing
  • FreeType
  • 병렬
  • Decompiler

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