2013-06-12 2 views
5

추론 된 템플릿이 잘못된 것으로 보입니다. 왜 (b)가 아닌 (c)가 호출 되었습니까?템플릿 공제가 잘못되었습니다.

#include <iostream> 
using namespace std; 
template<class T> void f(T){cout << "f(T)";}//(a) 
template<> void f<>(int*){cout << "f(int*)";}//(b) 
template<class T> void f(T*){cout << "f(T*)";}//(c) 
//void f(int*){cout <<"POD:f(int*)";}//(d) 

int main(int argc,char*argv[]) 
{ 
    int p = 1; 
    f(&p); 
    cout <<endl; 
    return 0; 
} 

출력 :

f(T*)

+7

참조 [기능 템플릿을 전문으로하지 왜 (http://www.gotw.ca/publications/mill17.htm). – juanchopanza

+1

@ jogojapan 질문을 더 잘 반영하기 위해 복제본의 제목을 변경했습니다. – juanchopanza

답변

3

좋아, 이제 우리가 처음이 바로 무엇을 설정할 수 있습니다.

(a)는 함수 템플릿입니다. (b)는 해당 기능 템플리트의 특수화입니다. (c)는 오버로드하는 다른 함수 템플리트 (a)입니다.

f(&p)을 작성할 때 두 가지 과부하 (두 개의 함수 템플리트, (a) 및 (c))가 있습니다. (c)에서 T*은 (a)의 T보다 전문화되어 있으므로 (c)가 선택됩니다.

이제 주석 처리 된 (d)을 고려해 보겠습니다. 이것은 함수 템플리트 (a)의 특수화가 아니라 추가 과부하입니다. f(&p) 호출을 해결하기 위해 고려해야 할 세 가지 오버로드가 있습니다. (d)는 템플릿이 아니며 &p 유형과 일치하는 int*이 있으므로 다른 두 개보다 우선 적용됩니다.

+0

(bx)은 이미 코드 (d)에 있습니다. – yuan

+0

@yuan oh. 내 눈은 단지 주석이 달린 코드를 읽었다. 젠장, 그들은 너무 잘 훈련 된거야 : ( –

0

템플릿 전문화가 템플릿 뒤에 있어야합니다. 다음은, 귀하의 경우, 그것은 다음과 같습니다

template<class T> void f(T){cout << "f(T)";}//(a) // Template 1 
template<> void f<>(int*){cout << "f(int*)";}//(b) // Specialization of template 1 
template<class T> void f(T*){cout << "f(T*)";}//(c) // Template 2, conceals template 1 

는 따라서, 당신은 인스턴스화 템플릿 2를 얻을. 올바른 방법 토이는 그것이 수행

template<class T> void f(T*){cout << "f(T*)";} // Template 1 
template<class T> void f(T){cout << "f(T)";} // Template 2 
template<> void f<>(int*){cout << "f(int*)";} // Specialization of the template 1 

출력 :

f(int*) 
관련 문제