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


실습과제 2-1 :


아래의 예처럼, 임의의 복합 형식 c 를 첫 번째 인수로 취하고 c 에 있는 모든 형식 x 를 형식 y 로 치환하는 삼항 메타함수 replace_type< c, x, y > 를 작성하라.



둘 이하의 인수들을 가진 함수 형식만 지원해도 된다.




풀이 : 


이 문제의 요점은 "특정 type 을 찾고, 그것을 다른 type 으로 바꾸기" 이다. 원하는 type 들이 template parameter 로 넘어 오게 된다. 이 문제를 푸는 것은 두 개의 단계로 나뉜다.

  1. 복합 형식 c 에서 x 형식을 찾아 내기.
  2. 형식 x 를 형식 y 로 바꾸기.


사실 복합 형식이 아닌 것을  변환하는 것은 그리 어렵지 않게 할 수 있다.



그렇지만 복합 형식은 어떻게 해야 할지 감이 잘 안 올 것이다. Template 특수화 중에서는 복합 형식에 대한 부분 특수화 표현이 있던 것을 기억할 것이다. 예를 들어 어떤 template 이 pointer 형에 대해서 특수화되기를 기대할 때 다음과 같은 식으로 표현했다.



마찬가지로 우리는 배열을 표현할 수 있다.



그런데 _tMain 의 위의 code 를 실행하면 두 번째 문장( 우리 실습 과제 중 하나인 문장이다 )에서 false 를 반환한다. 그 이유는 이 부분 특수화가 기본형을 가진 array 에 대해서만 동작하기 때문이다. 두 번째가 true 를 반환하게 하기 위해서는 다음과 같은  부분 특수화를 더 만들어 줘야 한다.



하지만 이 code 를 build 하면 주석에 나와 있는 것처럼 살포시 error 가 나 준다. 그 이유는 "type * [ N ]" 이라는 부분에서 compiler 가 '*' 를 pointer 형 선언이 아니라 곱하기 연산자로 인식해 버리기 때문이다. 그래서 "typedef 가 끝났는데 ';' 가 없다"고 주장하는 것이다.


이 문제를 해결하기 위해서는 typedef 의 첫 번째 type 을 pointer 형으로 만들어 주면 된다.



Build 해서 실행하면 둘 다 true 가 나오는 것을 알 수 있다.


이러한 code 를 보고 있다 보면, template 특수화라는 것이 정말 "개노가다" 작업임을 알 수 있다. 그 때문에 boost 같은 library 들은 macro 를 엄청나게 많이 사용하고 있는 것 같다. 실제 hpp 파일을 열어 보면 대부분이 macro 로 되어 있음을 알 수 있을 것이다.


마지막으로 함수와 관련한 meta function 을 살펴 보자. 여기에서 한 번 또 막히게 되는데, 이 부분만 이해하면 meta function 에 대해 더 많은 감이 오게 된다. 현재 예제의 함수는 두 개의 type 을 가진다. 하나는 return type 이고, 하나는 parameter type 이다. 이렇게 함수를 분해해 놓으면 좀 더 쉽게 형태를 이해할 수 있다.



함수를 위한 부분 특수화의 특이한 점이라고 하면 return_type 과 parameter_type 을 가지고 있다는 점이다. 책에서는 이를 blob pattern 이라고 회피해야 한다고 했는데, 이 경우에는 정말 어쩔 수가 없다. 물론 이것도 함수를 만들어 주는 meta function 을 만들면 어떻게 될 것 같기도 하다.


( * )는 이름없는 함수의 pointer 형식이다. 이를 typedef 하기 위해서 "typedef return_type ( *type )( param_type )" 과 같은 표현을 썼다. 잘 모르는 사람은 함수 포인터로 검색해 보기 바란다.


책에 있는 실습 과제를 푼 최종 code 는 다음과 같다. boost 같은 library 들을 보며 어떻게 하면 단순화할 수 있을 지 연구해 볼 필요가 있을 것 같다.



+ Recent posts