주의 : 공부하면서 정리하는 것이기 때문에 오류가 있을 수 있습니다.
실습과제 2-1 :
아래의 예처럼, 임의의 복합 형식 c 를 첫 번째 인수로 취하고 c 에 있는 모든 형식 x 를 형식 y 로 치환하는 삼항 메타함수 replace_type< c, x, y > 를 작성하라.
둘 이하의 인수들을 가진 함수 형식만 지원해도 된다.
풀이 :
이 문제의 요점은 "특정 type 을 찾고, 그것을 다른 type 으로 바꾸기" 이다. 원하는 type 들이 template parameter 로 넘어 오게 된다. 이 문제를 푸는 것은 두 개의 단계로 나뉜다.
- 복합 형식 c 에서 x 형식을 찾아 내기.
- 형식 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 들을 보며 어떻게 하면 단순화할 수 있을 지 연구해 볼 필요가 있을 것 같다.
'Programming > CPPTM' 카테고리의 다른 글
C++ Template MetaProgramming 실습 과제 3-2 풀이 (0) | 2012.11.25 |
---|---|
C++ Template Metaprogramming 실습 과제 3-1 풀이 (0) | 2012.11.24 |
C++ Template MetaProgramming 실습 과제 3-0 풀이 (0) | 2012.11.24 |
First class metadata (0) | 2012.11.22 |
[ 번역 ] Extracting Function Parameter and Return Types in C++ (0) | 2012.11.19 |
C++ Template MetaProgramming 실습 과제 2-3 재구현 (0) | 2012.11.17 |
C++ Template MetaProgramming 실습 과제 2-4 풀이 (1) | 2012.11.16 |
C++ Template MetaProgramming 실습 과제 2-3 풀이 (6) | 2012.11.15 |
C++ Template Metaprogramming 실습 과제 2-2 풀이. (1) | 2012.11.13 |
C++ Template Metaprogramming 실습 과제 2-0 풀이. (2) | 2012.11.13 |