2011-12-23 3 views
4

컴파일러에서 read1에 대한 일치 항목을 찾지 못하는 이유는 무엇입니까? read1read2의 차이점을 볼 수 없습니다. Foo 클래스의 중첩 typedef 템플릿에 대한 제한이 있습니까?C++ 템플릿 함수 인수로 typedef 템플릿

template<typename T> 
class Handle{}; 

class Foo{ 
public: 
    typedef Handle<Foo> Handle; 
}; 


template<typename T> 
void read1(typename T::Handle){} 

template<typename T> 
void read2(Handle<T>){} 


int main(int argc, char** argv) 
{ 
    Foo::Handle f1;  
    read1(f1); 

    Foo::Handle f2; 
    read2(f2); 
} 

G ++ 컴파일러 출력 (G ++ 4.4.5) 먼저

g++ -c -I. main1.cpp 
main1.cpp: In function ‘int main(int, char**)’: 
main1.cpp:37: error: no matching function for call to ‘read1(Handle<Foo>&)’ 
+0

중복 된 '내부'네임 스페이스를 제거하고 예제를 간결하게 유지하십시오. – Xeo

+0

G ++ 4.4.5로 편집하면 코드가 깨집니다. g ++ -c main.cpp main.cpp : 8 : 오류 : 'typedef class Handle을 선언합니다. Foo :: Handle' main.cpp : 3 : 오류 : 변경 의미 '핸들에서'클래스 핸들 ' main.cpp :'int main (int, char **) '함수에서 : main.cpp : 27 : 오류 :'read1 (핸들 &) '' –

답변

4
Foo::Handle f1;  
read1(f1); 

Handle<Foo>하지 푸이다.

템플릿은 상속되지 않습니다. Handle<Foo>은 푸 (Foo)가 아닌 별개의 클래스이므로 Handle<Foo>::Handle이 없습니다.

3
template<typename T> 
void read1(typename T::Handle) 
{ 
} 

, 당신은 read1<Foo>(f1)처럼 명시 적으로 템플릿 매개 변수를 제공하지 않고이 함수를 호출 할 수 없을 것입니다. SFINAE에서 읽으십시오.

둘째로, 컴파일러는 어떻게 을 찾아야합니까? T은 무엇입니까? 당신이 쓰는 모든 가능한 클래스의 모든 중첩 된 typedef를 테스트해야 할 것입니다. 불가능한 것 같니? 그것은. 타입은 전달되는 READ1

+2

당신이 쓸 수있는 모든 클래스를 테스트 할 필요는 없습니다. read1 호출 시점에 정의 된 클래스 만 테스트하면됩니다. 가능 (컴파일러가 템플리트를 처리하는 데 필요한 일부 작업과 비교해도 쉽다). 그러나 표준별로 수행되지는 않습니다. –

+0

왜 read2와 같은 인수를 찾을 수 있습니까? 단지 Foo를 테스트 할 필요가 있습니다. 다른 타입이 없습니다. –

+0

그 시점에서 정의 된 모든 클래스를 테스트해야 할뿐만 아니라 가능한 모든 템플릿 인스턴스화 (템플릿 양식에서도 가능할 수 있습니다). 그러나 모호성은 어떻게 해결할 것인가? 일반적으로 프로그래머는이를 수정해야하지만,이 경우 완전히 다른 관련 코드 변경 (다른 네임 스페이스 및 모두)이있을 수 있으므로 모호성이 발생할 수 있으므로 프로그래머가이를 수정하면 실제로 옵션이되지 않습니다. @ José :이 간단한 예제에서는 foo 만 테스트하면되지만, 대부분의 scnearious는 더 복잡하고 대부분의 경우 작동하지 않는 언어 기능이 그다지 인기가있는 것은 아닙니다. – Grizzly

관련 문제