2013-05-26 5 views
7

다음 코드는 gcc와 clang으로 잘 컴파일됩니다. 오버로드 확인이 첫 번째 오버로드합니다 (identity<T>::type 하나를) 선택처럼왜 이러한 과부하가 모호하지 않습니까?

template <typename T> 
struct identity 
{ 
    typedef T type; 
}; 

template <typename T> 
void foo(typename identity<T>::type); 

template <typename T> 
void foo(T); 

int main() 
{ 
    foo<int>(0); 
} 

것 같습니다.

과부하가 모호하지 않은 이유를 설명 할 수 있습니까? 내가 말할 수있는 한, 유일한 차이점은 첫 번째 인수가 추론되지 않은 컨텍스트이고 두 번째 인수의 인수가 아니라는 점입니다. 그러나 템플릿 인수를 명시 적으로 제공하고 있으므로 필자는 왜 그것이 중요해야하는지 알지 못한다.

+0

흥미 롭습니다. 분명히'foo (0)'이 아니라'foo (0)'을 명시 적으로 인스턴스화하지 않아서 유형 공제를 가능하게 한 경우 두 번째 함수가 선택되었을 것입니다 (신원 메타 함수에 대한 유형 공제가 없음)[email protected] 앤디 프록 (Anty Prowl) : 당신의 대답에 의문을 제기하고 싶지는 않습니다. foo 매개 변수에 기본값을주고 매개 변수없이'foo ()'을 호출하십시오. 귀하의 논쟁은 여전히 ​​적용되어야하지만, 과부하는 실제로 HighCommander4가 예상 한 것처럼 모호합니다. 함수 템플릿의 명시 적 템플릿 인스턴스화는 복잡합니다. –

답변

7

과부하는 모두 가능하지만 전자는 보다 특수화 된이므로 과부하 해결로 인해 선택됩니다. 과부하 해상도에 문단 C++ 11 표준의 13.3.3/1 인분

:

[...] 가능한 기능 F1 다른 가능한 기능 함수보다 더 정의된다 F2 모든 인수 i를 들어, ICSi(F1) 다음 더 나쁜 변환 ICSi(F2)보다 시퀀스 및

없는 경우 - 일부 인수 J에 대한, ICSj(F1)이 아니라면, 그,

ICSj(F2)보다 더 나은 변환 순서, 또는

- 컨텍스트는 사용자 정의 변환 (8.5, 13.3.1.5 및 13.3.1.6 참조) 및 표준 변환 시퀀스 (F1의 반환 유형에서 대상 유형 (즉, 엔티티가 초기화 됨)은 의 반환 유형 인 F2에서 대상 유형까지 표준 변환 시퀀스보다 우수한 변환 시퀀스입니다. [...] 또는

아니라 그 경우 - F1 비 템플릿 함수이며

아니라 그 경우 F2는 함수 템플릿 특수화 또는 - F1F2 기능 템플릿 전문이 F1의 함수 템플릿은 14.5.6.2에 설명 된 부분 순서 규칙에 따라 F2의 템플릿보다 더 특수화 된 입니다.

다른 14.5.6.2/2 단락에서 설명되는 것보다 더 특수화 두 함수 서식하는 판정 공정 :

부분 순서 선택 두 함수 템플릿보다 특수화 다른 하나는 차례로 각 템플릿을 변환하고 (다음 단락 참조) 함수 유형을 사용하여 템플릿 인수 공제를 수행합니다. 공제 프로세스는 템플릿 중 하나가 다른 것보다 더 전문화되어 있는지 여부를 결정합니다. 이렇게하면 부분적인 순서 지정 프로세스에서 선택한 템플릿이 더 특수화됩니다.

+0

의미가 있습니다. 고마워요! (필자는 의도적으로 "보다 전문화 된"을 "작은 유형의 입력 유형에 적용"이라는 의미로 생각했지만 의도의 기술적 정의가 정확히 의미하는 것은 아닙니다. – HighCommander4

+0

@ HighCommander4 : 도움이 되니 기뻤습니다 :) 당신이 직감을 잘못하면 될 수도 있지만, "더 작은 유형의 입력 유형에 적용됩니다"라는 직감은 의미가 있습니다. –

관련 문제