다음 2 가지 과부하를 고려하십시오
template<typename T>
bool test() {
return true;
}
template<template<typename ...> class T>
bool test() {
return false;
}
첫 번째 클래스는 일반 클래스에서 작동하고 두 번째 클래스는 인스턴스화되지 않은 템플릿에서 작동합니다. 예를 들어 :
std::cout<<test<int>()<<std::endl; <-- this yields 1
std::cout<<test<std::list>()<<std::endl; <--this yields 0
이제 다음 템플릿 기능을 고려하십시오.
template<typename U>
bool templfun(){
struct A{
bool f(){
return test<A>(); // <-- this gives an error
}
};
return test<A>(); // <-- this is ok
}
GCC에서는 Clang이 컴파일하는 동안 모호한 과부하 해결에 오류가 발생합니다. 흥미롭게도 test ()에 대한 두 번째 호출은 오류를 생성하지 않습니다 (GCC에서도). 또한 template<typename U>
templfun 위에 있는 것을 제거하면 gcc는 불평을 멈 춥니 다.
이것은 GCC의 버그입니까, 아니면 불법 코드입니까?
답변
GCC가 잘못되었습니다. struct A
A는 템플릿 실체 분명하지만 이 아닌 템플릿 (그것이로 시작하지 않는 한 template
, 그래서 모호함이없는 키워드).
확인하기 위해 type 매개 변수의 이름을 바꾸어 G ++이 템플릿 템플릿 오버로드를 사용하려고한다는 것을 알 수 있습니다.
template <typename X>
bool test() {
return true;
}
template <template <typename...> class Y>
bool test() {
return false;
}
template <typename U>
bool templfun() {
struct A {
bool f() {
return test<A>(); // <-- this gives an error
}
};
return test<A>(); // <-- this is ok
}
bool run() {
return templfun<int>();
}
G ++ 출력 : ( godbolt 링크 )
<source>:15:27: error: call of overloaded 'test<templfun() [with U = int]::A>()' is ambiguous
15 | return test<A>(); // <-- this gives an error
| ~~~~~~~^~
<source>:2:6: note: candidate: 'bool test() [with X = templfun() [with U = int]::A]'
2 | bool test() {
| ^~~~
<source>:7:6: note: candidate: 'bool test() [with Y = templfun()::A]'
7 | bool test() {
| ^~~~
분명히 ” candidate: 'bool test() [with Y = templfun()::A]'
“는 가짜입니다.
C ++ 11 이전에는 로컬 형식이 템플릿 인수로 허용되지 않았으므로 (C ++ 03 § 14.3.1.2 참조) G ++ 구현의 복잡성을 설명 할 수 있습니다.