주의 : 공부하면서 정리한 내용이므로 오류가 있을 수 있습니다.


실습 과제 3-4 :


twice 를 그 자신에 대해 사용해서 T 를 T**** 로 변환하라.




풀이 :


처음에 한 구현은 다음과 같다.



하지만 생각해 보니 위와 같이 구현하면 3-3 의 문제를 푸는 것과 다를 것이 없었다. 여기에서 의도하는 것은 twice 라는 메타 함수를 자신의 메타 함수로 사용해 f( f( x ) ) 와 같은 식으로 사용해서 호출하는 방법을 알고 있는 지를 물어 보는 것이라는 생각이 들었다.


즉 다음과 같은 형태여야 한다.



일단 메타 함수를 파라미터로 넘기기 위해서는 lambda 나 placeholder 를 사용해서 이를 일급 메타 함수로 만들어 줄 필요가 있다는 것까지는 쉽게 생각할 수 있었다. 하지만 이 부분부터가 어렵다. 즉 고차 메타 함수에 대한 이해를 제대로 하고 있는지를 확인하는 문제라 생각한다. 만약 제대로 이해하고 있지 못하다면 책을 다시 한 번 살펴 볼 필요가 있다. 필자도 다시 봤다 ㅠㅠ. 특히 "3.3 자리표 다루기" 를 유심히 보기 바란다.


일단 답부터 말하자면 다음과 같이 호출해야 한다.



위의 코드를 좀 더 이해하기 쉽게 분해하면 다음과 같다.



3.3 절에서도 이야기하고 있듯이 boost::add_pointer 는 메타 함수 클래스가 아니다. 메타 함수 클래스는 다음과 같은 정의를 가지고 있기 때문이다.


메타함수 클래스는 공개적으로 접근할 수 있는 apply 라는 이름의 내포된 메타함수를 가진 클래스이다.

- C++ Template Metaprogramming, 3.1.4, 64 페이지.


즉 apply 를 평가하려는 시점에 boost::add_pointer< _1 >::apply 가 존재하지 않으므로 컴파일에 실패하게 된다. 


그러므로 우리는 mpl::lambda 를 사용해 add_pointer 를 메타 함수 클래스로 만들어 줘야만 한다. mpl::lambda 가 메타 함수 클래스를 만들어 주는 원리에 대해서는 mpl::lambda 의 원리에서 다루고 있으니 참조하기 바란다.


이 시점에서 의문을 품는 사람들이 있을 것이다. 필자도 그랬다. 왜 실습과제 3-3 은 메타 함수 클래스가 아닌 add_pointer 를 그냥 호출할 수 있는 것일까? 



그 이유에 대한 의문을 외쿡인들도 가졌던 것 같다. CPPTM Answers - Exercise 3-4 에 보면 거기에 대한 질문과 답변이 있으니 꼭 참조하시기 바란다.




추가 : 필자는 위의 링크를 보고 제대로 이해를 못해 나름대로 답을 찾으려고 노력했고 그 내용을 정리해 보았다. C++ Template MetaProgramming 실습 과제 3-4 풀이 보충을 참고하라.

+ Recent posts