2011-10-14 2 views
2

Sun Studio에서 템플릿 클래스에 템플릿 클래스를 제공하는 데 문제가 있습니다. 이 코드는 GNU G ++ (4.4.1 및 4.4.3)에서 제대로 컴파일되지만 Sun Studio C++ (5.9 SunOS_sparc 패치 124863-01 2007/07/25)에서는 실패합니다.템플릿 클래스의 템플릿 친구가 Sun Studio C++에서 실패 함

// Forward declarations 
template<class T> class M; 
template<class T> void f(M<T>, M<T>); 

// Define M<T> 
template<class T> 
class M 
{ 
public: 
    void f(M<T>) { } 

    friend void ::f<>(M<T>, M<T>); 
}; 

// Define global function f 
template<class T> 
void f(M<T> a, M<T> b) 
{ 
    a.f(b); 
} 

M<int> a; 

내가 CC -c -o t3.o t3.cpp를 통해 컴파일하려고, 나는 다음과 같은 오류 메시지가 얻을 :

"t3.cpp", line 12: Warning: A friend function with template-id name must have a template declaration in the nearest namespace. 
"t3.cpp", line 22:  Where: While specializing "M<int>". 
"t3.cpp", line 22:  Where: Specialized in non-template code. 
"t3.cpp", line 12: Error: Global scope has no declaration for "f". 
"t3.cpp", line 22:  Where: While specializing "M<int>". 
"t3.cpp", line 22:  Where: Specialized in non-template code. 
1 Error(s) and 1 Warning(s) detected. 

이것이 ++ 썬 스튜디오 C의 문제인가, 또는 여기에

는 최소한의 예입니다 C++이 유효하지 않습니까? (여전히 GCC에서 허용되며 -Wall -pedantic과 함께 경고가 표시되지 않습니다)? 코드를 변경하여 GCC와 Sun Studio에서 모두 표준을 따르고 컴파일 할 수있는 우아한 방법이 있습니까?

미리 감사드립니다.

+1

그것의 선 스튜디오에 문제가, 그것이 아주 나빴어. 부스트 소스를 보면 상황을 해결하는 방법에 대한 많은 아이디어가 있습니다. – PlasmaHH

+0

감사합니다. 그런 다음 부스트 소스를 확인해 보겠습니다. – felix

+0

나는 부스트 소스에서 약간의 브라우징을 해왔다.이 문제를 해결하는 가장 효과적인 방법은'# ifdef'를 사용하는 것이다 : Sun Studio (그리고 이것이 작동하지 않는 다른 컴파일러)에서 간단하게 필요한 것들을'protected' 나'private' 대신'public'으로 만들고'friend' 문을 제거합니다. – felix

답변

3

성공적으로 "CC : 일 C++ 5.8 패치 121017-13가 2008년 1월 2일"사용하여 코드를 컴파일 친구에게 템플릿 선언을 추가 :

template<class T> 
class M 
{ 
    ... 
    template <class A> 
    friend void ::f(M<A>, M<A>); 
    ... 
}; 

를 수행하면 원래의 질문에 대한 답변하지 않습니다를하지만, 친구 템플릿 클래스가 원인 이유를 찾고있는 사람들 "오류 : 대한 여러 선언"오류가 썬 CC 컴파일러를 사용하여 컴파일, 그냥 같이, 친구 클래스 선언을 앞으로 추가

template <typename T> class B; //will fail without forward declaration 

class A 
{ 
    private: 
    template <typename T> friend class B; 
}; 

template <typename T> class B {}; 
+0

고마워, 정말 도움이 됐어. – Hitobat

+0

re : 당신의 2 번째 대답, 나는 부스트를 구축하려고 시도하는 동안 다소 이상한 상황에 직면했습니다. 코드는 다음과 유사합니다 :'template class A; 템플릿 클래스 A {템플릿 클래스 impl; 템플릿 친구 클래스 impl; 템플릿 class impl {};/* ... * /'... 중첩 된'impl' 클래스는'Multiple declaration ... '에러를 얻습니다.내가 해결할 수있는 유일한 방법은 전방 선언을 제거하고 friend 선언문을 클래스 본문 뒤에 놓는 것입니다. –

0

Sun의 컴파일러는 경향이 있으며 g ++와 같은 컴파일러보다 자주 업데이트되지 않습니다. 이 경우 전역 템플릿 함수를 섀도 잉하는 클래스에 의해 컴파일러가 혼란스러워하는 것 같습니다.

내가 직접 사용자의 문제를 해결하는 방법을 알아낼 수 있지만, 가능한 해결 방법이 있습니다 :

  • 그냥 클래스에서 서식 그림자하지 않습니다는. 예를 들어 세계 f 및 친구의 이름을 foo으로 변경하면 Sun에서 컴파일 할 수 있습니다. 기능이 관련이없는 경우 특히 유용합니다.
  • 공용 인터페이스를 M으로 확장하여 우정의 필요성을 피하십시오.