이번 항목은 나에게 큰 충격을 주었다. "이렇게 되는 구나." 싶었기 대문이다. 특수화를 하지 말아야 하는 이유가 절대적인것은 아니지만, 조심해야 하는 이유로써는 충분하다.

소크라테스의 교육법대로, 질문을 통해서 진행한다.


1. C++에 존재하는 템플릿의 두 가지 종류는 무엇이며, 각각 어떻게 특수화하는가?

알다시피 템플릿의 두 가지 종류는 "클래스 템플릿" 과 "함수 템플릿" 두 가지가 있다. 이 두가는 링크를 통해서 정리한다.

IT 전뇌실/C++ Template

첫번째 질문은 이 링크로 대체 할 수 있다. 이제 본론으로 넘어가서 두번째 질문을 던져보자.


2. 다음 코드의 마지막 줄에서 호출되는 것은 어떤 f일까? 그리고 왜 그것이 호출 될까?

나는 이 코드를 보고, 나는 경악을 했다. 그 이유는 차근 차근 정리해 나가고, 이 코드들이 무엇인지 정리해보자.


1~2 라인 코드,

함수 템플릿 f 를 정의한 것이다.


4~5 라인 코드,

1~2 라인 코드를 특수화 하여 int* 에 특화 시킨 것,


7 ~ 8 라인 코드,

함수 템플릿 f 를 오버로딩 한 것이다.


12 ~ 13 라인 코드,

무엇이 호출 될 것인가? 를 나타내는 라인


이 마지막 질문에 답하기 위해선 "함수 템플릿이 어떻게 호출 될까?"를 알아야 할 것이다.

1. 템플릿이 아닌 일반 함수가 있다면, 무조건 그것이 1등으로 호출 한다.

2. 1번이 안된다면, "기본 템플릿 함수"을 찾는다.

3. 2번에 의해 찾은 "기본 템플릿 함수"가 있다면, 특수화버전과 맞는지 찾으며, 있다면 특수화를 우선적으로 호출, 없다면, 템플릿 매개변수에 맞는 "구체적인 기본 템플릿 함수"를 인스턴스화 하여, 호출한다. 만약 "구체적인 기본 템플릿 함수"가 여러개이거나 없다면, 컴파일 타임 에러를 벹어 낸다.


그렇다면, 위의 코드 중에 무엇이 호출 될까? 나는 위의 코드중 4~ 5 라인의 특수화 함수가 호출 될 것이라고 판단했고, 그 이유는 "템플릿 함수 호출 순서"에서 처럼, 기본 템플릿 함수가 있고, 특수화 된게 있으니 특수화가 우선적으로 호출 될 것이다"라고 생각 했기 때문이다. .. 책 내용을 읽다 보면, 섬짓한 정도로, .. 독자를 꾀뚫는다.

.. 바로 이렇게 생각했다는게 틀린 이유이기 때문이다.

"함수 템플릿이 어떻게 호출 될까?" 에서 2번째 순서가 먼저이기 때문에, "특수화가 무엇이 되었는지 생각하기 전에, 기본 템플릿 함수 7 ~ 8 라인이 선택된다." 는 것이다.

.. 그러므로 7 ~ 8 라인의 함수가 호출 되어 진다.

다음 코드는 그 증면된 코드이니 한번 살펴 보기 바란다.


자 확인이 되었으니, 대처방안을 생각해 보자. 생각해 보면, 특수화 자체를 안 쓸 수는 없기 때문에, 쓰긴 쓰되 좀 더 쌔련되게 써야 할 것이다. 그러면서 함수 템플릿 오버로딩이 필요하다면, 함수 템플릿 오버로딩을 쓰되 위의 문제를 피해 가야 할 것이다.

.. 책에선 이 방법이 소개 되었다. 나는 이 방법을 소개 하지 않고, 마치려 한다.(궁금하다면 역시 책을 봐야 할 것이다.)


총평

함수 템플릿을 오버로딩 하는것과 특수화 하는것의 차이점을 이해하고, 우선순위가 무엇이 더 높은지 알아가는 항목이였다. 이 항목을 통해서, 함수 템플릿이 위험할 수 있다는 것을 알게 되었다. .. 그 대처방법은 곰곰히 생각해 보는 것도 나쁘지 않을 것이라고 생각하고, 이번 항목을 마치려 한다.

역시 심오한 C++의 세계..


posted by 농사를 짓는 게임 프로그래머 최익필

댓글을 달아 주세요

  1. 최익필안티 2009.01.11 14:28  Addr  Edit/Del  Reply

    배신자

  2. loveintowind 2009.07.10 14:56  Addr  Edit/Del  Reply

    visual studio 2008에서 빌드를 하면 int * 로 특수화 한 부분에서 컴파일 에러가 납니다. int로 특수화 해야 에러 없이 빌드가 되며 int로 특수화 하고 int *를 인자로 받을 경우 문제 없이 원하는 결과를 얻을 수 있습니다.