주의 : 공부하면서 정리한 것이기 때문에 오류가 있을 수 있습니다.


실습 과제 2-3 :


형식 특질 수단들을 이용해서, 그 인스턴스를 스트림에 넣었을 때 템플릿 매개변수의 형식 이름을 출력하는 type_descriptor 클래스 템플릿을 작성하라( 실행시점 형식 정보( RTTI )로 같은 효과를 얻을 수는 없다. C++ 표준의 18.5.1 [ lib.type.info ] 에서의 문단 7 에 따르면, typeid( T ).name() 이 의미 있는 결과를 돌려 준다는 보장이 없기 때문이다 ).



type_descriptor 의 템플릿 매개변수가 char, short int, int, long int 로만 구성된 복합 형식이라고 가정해도 좋다.




삽질 : 


이 문제를 풀기 위해서는 앞의 실습 과제들에서 했듯이 복합 형식을 분리할 수 있어야 한다. 그런데 굳이 모든 템플릿 특수화를  할 필요는 없다고 생각할 수 있다. 왜냐하면 문제에서는 "형식 특질 수단들을 이용해서"라고 했기 때문에 boost 의 meta function 들을 사용하면 된다고 생각했다.


그러나 boost 에는 is_integral 과 is_float 은 있지만 아쉽게도 is_char, is_short 같은 것은 존재하지 않는다. 그러므로 특수화를 하지 않고서는 이 문제를 해결할 수 없다.


그리고 복합형식인 경우와 복합형식이 아닌 경우를 구분할 수 있어야 한다. 그렇다면 우리는 몇 가지 패턴을 생각해 볼 수 있다.


  • T
  • const T
  • T const
  • T*
  • const T*
  • T const*
  • T* const
  • T&
  • const T&
  • T const&
  • T& const


그런데 이 각각의 경우에 과제에서 제시한 4 가지 형식이 결합되면 경우의 수는 ( 4 X 11 = ) 44 이며, 그에 대응해 특수화를 해야 한다. 문제에는 나와 있지 않지만 참조까지 고려하면 장난이 아니다. 여기에서 const T 와 T const 가 같고, const T* 와 T const*, const T& 과 T const& 이 같기 때문에 이를 배제하면 경우의 수는 ( 4 X 9 = ) 36  이다. 그러나 아직까지도 포인터의 참조라든가 이런 조합도 있기 때문에 특수화로는 답이 안 나온다.


어쨌든 일단은 두 개가 template 에서도 같은 복합형식으로 인지되는지 확인부터 해 봤다.



일단 다행히도 같은 형식으로 취급되었다.


이제 어떻게 하면 특수화를 줄여 볼 수 있을까라는 고민으로 이어졌다. 한참을 고민하다가, 한글을 완성형으로 하면 개수가 많아지고 조합형으로 하면 개수가 줄어들 듯이 그런 방법을 사용하면 어떨까 하는 생각이 들었다. 그러나 어떻게 하면 조합할 수 있을지 상상이 안 가서 결국엔 포기하고 googling 을 하고 말았다.


http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?CPPTM_Answers_-_Exercise_2-3


link 를 보는 순간 문제를 잘 못 이해하고 있었다는 생각이 들었다. 문제에서는 다음과 같은 형태로 출력하라고 되어 있다.



다음과 같은 형태가 아닌 것이다. 



계속해서 meta function 의 type 이나 value 를 가져다 쓰는 예제를 보고 있다가 보니 완전히 착각한 것이다. 사람의 고정관념이라는 것은 참 무섭다는 생각이 든다. 뭐 구현을 보면 문제를 제대로 이해하고 있더라도 엄청난 노가다를 하던가 제대로 풀지 못했을 것 같기는 하다. 가끔 template metaprogramming 을 사용해 문제 해결을 잘 하는 사람들은 천재가 아닐까라는 자기비하적인 생각도 든다.


풀이 : 


어쨌든 함수 호출 순서대로 설명하면 가장 먼저 정의할 것은 "<<" 연산자에 대한 overloading 이다. 이 연산자는 별건 없고 type_descriptor::print() 함수를 호출해 준다.



그 다음에는 type_descriptor template class 를 만들어야 한다. 그 안의 print() 함수는 boost 의 meta function 들을 사용한다. 일단 형식을 출력하는 순서를 정해야 한다. 그런데 각각의 형식이나 한정자들은 마치 차원이 다른 것처럼 동작하고 있기 때문에 tree 를 타고 내려 가듯이 재귀함수처럼 구현한다. 주의할 것은 다음 단계로 넘어 가기 전에 한정자나 포인터, 그리고 참조를 제거하고 항상 제일 앞에 단일 형식이 존재하는 것처럼 취급한다는 것이다.



전체 코드는 다음과 같다.




위의 링크에 들어가 보면 지금 구현이 가진 한계에 대해서 지적하고 보충하는 댓글들이 있다. 한 번씩 읽어 보면 도움이 더 많이 될 것이라 생각한다. 


여기에서는 단순한 형태에 대해서만 다루고 있다. 이것을 배열과 함수에 대해서 확장하기 위해서는 "실습 과제 2-5 풀이"를 참조하라.

+ Recent posts