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


"C++ Template MetaProgramming 실습 과제 3-4 풀이" 와 "[ 번역 ] CPPTM Answers - Exercise 3-4" 에도 불구하고 아직도 이해가 안 가는 사람들이 많을 것이라 생각한다. 번역 글에서 논쟁하는 것을 살펴 보고 있어도 뭔가 머리에 쏙 들어 오는 것이 없을 것이다. 그냥 이해가 가는 사람이 있다면 존경하고 싶다.


필자도 그래서 책을 몇 번이나 다시 보고 여러 가지 코드를 테스트해 보았다.


일단 다음과 같은 코드를 컴파일해 보자.



뭔가 오류가 주저리 주저리 나오는 데 우리가 주목할 것은 마지막 "with[ ... ]" 에 나와 있는 내용이다.


1>d:\mywork\templatemetaprogramming\consoleapplication\consoleapplication.cpp(24): error C2039: 'type' : 'boost::mpl::apply<F,T1>'의 멤버가 아닙니다.

1>          with

1>          [

1>              F=twice<int *,int> *,

1>              T1=twice<int *,int>

1>          ]


위의 오류는 처음 apply 가 평가될 때, 즉 내부 twice 가 평가될 때의 오류를 의미하고 있다. twice 메타 함수의 다음 코드 부분이다.



원래는 mpl::apply 가 적용되고 나면 boost::add_pointer< T > 가 실행되면서 그것의 내포된 type 에 접근해야 하는데, 그것이 실패하면서 "boost::mpl::apply< F, T1 > 의 멤버가 아닙니다" 라는 오류를 뱉어 낸다. 왜 그럴까?


"F = twice< int*, int >*" 가 들어 오고 "T1 = twice< int*, int >" 가 들어 왔다. 아무래도 이것만 봐서는 좀 이해가 안 된다.


그래서 자리표 표현식을 다음과 같이 바꿔 호출해 보았다.



다음과 같은 오류를 낸다.


1>d:\mywork\templatemetaprogramming\consoleapplication\consoleapplication.cpp(24): error C2039: 'type' : 'boost::mpl::apply<F,T1>'의 멤버가 아닙니다.

1>          with

1>          [

1>              F=twice<int *,int> *,

1>              T1=int

1>          ]


"T1 = int" 로 평가되고 "F = twice< int*, int >*" 라고 평가된 것을 볼 수 있다. 즉 내부 twice 의 boost::add_pointer 가  메타 함수 클래스로서 평가되는 것이 아니라, 그냥 메타 함수로 평가되어 버렸다는 것을 알 수 있다.


정리하자면 "F = twice< add_pointer_f, int >*" 식으로 들어 와야 하는 것이, boost::add_pointer< int >::type 으로 평가되어 버렸기 때문에 "F = twice< int*, int >*" 가 되어 버린 것이다( boost::add_pointer< int >::type 은 int* 이기 때문이다 ).


그래서 우리가 mpl::lambda 메타 함수를 사용해 이 자리표 표현식을 메타 함수 클래스로 만들어 주지 않으면 컴파일 에러가 나는 것이다.


+ Recent posts