2013-02-23 12 views
11

Clang 3.2의 버그 또는 C++ 03의 위반인지 확실하지 않지만 템플릿 클래스의 템플릿 생성자에 대한 명시 적 인스턴스화는 실패하지만 템플릿 기반 인스턴스의 명시적인 인스턴스화는 실패합니다 템플릿 클래스의 멤버 함수가 성공합니다. 예를 들어템플릿 클래스에 대한 템플릿 생성자의 명시 적 인스턴스화

에 문제없이 다음 컴파일 모두 그 소리 ++와 g ++ : ++ g으로 경고없이 다음 컴파일 반면

template<typename T> 
class Foo 
{ 
public: 
    template<typename S> 
    void Bar(const Foo<S>& foo) 
    { } 
}; 
template class Foo<int>; 
template class Foo<float>; 

template void Foo<int>::Bar(const Foo<int>& foo); 
template void Foo<int>::Bar(const Foo<float>& foo); 
template void Foo<float>::Bar(const Foo<int>& foo); 
template void Foo<float>::Bar(const Foo<float>& foo); 

그러나 ++ 그 소리와 함께 실패합니다 특히

template<typename T> 
class Foo 
{ 
public: 
    template<typename S> 
    Foo(const Foo<S>& foo) 
    { } 
}; 
template class Foo<int>; 
template class Foo<float>; 

template Foo<int>::Foo(const Foo<int>& foo); 
template Foo<int>::Foo(const Foo<float>& foo); 
template Foo<float>::Foo(const Foo<int>& foo); 
template Foo<float>::Foo(const Foo<float>& foo); 

, I 다음과 같은 두 가지 오류 메시지가 표시됩니다.

TemplateMember.cpp:12:20: error: explicit instantiation refers to member 
     function 'Foo<int>::Foo' that is not an instantiation 
template Foo<int>::Foo(const Foo<int>& foo); 
       ^
TemplateMember.cpp:9:16: note: explicit instantiation refers here 
template class Foo<int>; 
      ^

위반 사항 clang의 표준 또는 버그의 버그?

+3

유효한 C++ 03처럼 보입니다. 아마 Clang의 버그 ++ –

답변

5

GCC 버그를 찾은 것 같습니다. 이들은 모두 암시 적으로 선언 복사 생성자 이름 : [temp.explicit] P4 당

template Foo<int>::Foo(const Foo<int>& foo); 
template Foo<float>::Foo(const Foo<float>& foo); 

,

명시 적 인스턴스화 이름의 선언 암시 적으로 선언 특별한 멤버 함수의 경우를 (제 12) , 프로그램이 잘못 형성되었습니다.

따라서 Clang은이 코드를 거부해야합니다.

+0

리차드 감사합니다! 당신은 절대적으로 맞습니다. 명시 적으로 생성자 Foo (const Foo & foo)를 선언하고 복사 생성자의 명시적인 인스턴스화를 제거하면 프로그램이 Clang으로 컴파일됩니다. –