내가 STL에 조예가 깊어서 글을 남기는 것이 아니라, Effecitve STL 을 공부하는 사람들이 이 글을 보고, 도움이 되었으면 하는 생각과, 혹시 내가 틀린것이 있다면 지적해 주시지 않을까 란 생각으로 글을 올리는것임을 미리 밝힙니다. - 최익필

이번 항목은 한참 해맷다. 4시간 정도.. 화딱지 나는 항목이였다. 객체지향 프로그램밍으로 코드를 짜다보면 함수를 함수 객체로 만들어야 할 때가 있다. 이런 함수 객체를 다시 다른 함수객체를 만들기 위해선 코드를 다시 짜야 하는데, 이 과정이 무척 귀찮다. 그래서인지 STL에선 다른 형태로 함수 객체를 변경하는 어댑터를 제공한다.

어떠한가? 흥미롭지 아니한가? 그렇기 때문에, 함수 객체를 만들고자 한다면, 어댑터 적용이 가능하게끔~ 하자는 이야기가 이번 항목이다.

이 어댑터가 적용되게 하려면, 한가지 규칙을 따라야 한다. 바로 어댑터가 사용하는 typedef 를 정의해 두어야 한다는것 이다. 어댑터가 사용하는 typedef는 argument_type, first_argument_type, second_argument_type, result_type 4개이다.

이런 추가 작업이 좀 귀찮았는지 STL에선 STL에선 typedef가 정의된 템플릿(template struct unarry_function, bainary_function 이 std 에 정의되어 있다.) 구조체(클래스여도 상관없다. 개인취향)를 제공하고 있으며, 이것을 상속하면 손 쉽게 정의 가능해 진다.

어댑터 만들때의 헬퍼


아래 코드는 형태 변환할 때의 요구 사항


이런식으로 말이다.

왜 이것 때문에 4시간동안 해맸는가?
p.256의 예제코드로 컴파일을 하여도 컴파일이 되지 않았기 때문이다. predicate class 정의 시 operator 는 매개변수를 레퍼런스로 받는 시그네처를 가진 구조였다. ptr_fun 은 잘되었지만 ptr_fun 으로 반환된 함수 객체를 not1 는 받아 들이지 못했다. 그래서 다 타고 들어가서 시그네처를 확인했다.

그게 4시간이나 걸렸다. .. 컴파일 에러만 잘 조사했더라면 금방 끝났을 텐데, 문제의 원인은 ptr_fun 을 만들면서 argument_type 이 레퍼런스로 정의되어지고(템플릿으로 컴파일 타임에 인스턴스화 된다.) not1 에서의 operator() 가 레퍼런스로 받는 구조가 되면서 레퍼런스의 레퍼런스를 인자로 받게 된다.

확인 코드


보면 알겠지만 ptr_fun 으로 만들어진 함수 객체의 argument_type 을 받아 들이고, not1 으로 만들어진 함수 객체는 bool operator( const typename _Fn1::argument_type& _Left ) 로 정의되면서 (argument_type&)& 가 되어진다. .. std 를 변경할수 없으니 .. 함수 매개자를 값에 의한 복사로 처리하여 해결하였다. (포인터가 더 효과적이거나 piml 구조로 클래스를 만드는 습관을 길러야 할듯)


자세한 기본 내용은
"C++ Standard Library 레퍼런스 튜토리얼" 책을 보면 매우 자세하게 나와 있다.


2009년 4월 16일
이제는 이런 고민자체를 하지 않는다. 왜냐하면 boost::bind를 사용하기 때문이다. ...

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기