2010-03-28 4 views
2

아래에 나와있는 것처럼 중첩 클래스의 정규화 된 이름을 사용하려고 시도했지만 컴파일러가 숨막히는 것입니다!gcc가 중첩 클래스에서 오류를 반환합니다.

template <class T> class Apple { 
    //constructors, members, whatevers, etc... 
public: 
    class Banana { 
    public: 
     Banana() { 
      //etc... 
     } 
     //other constructors, members, etc... 
    }; 
}; 

template <class K> class Carrot{ 
public: 
    //etc... 
    void problemFunction() 
    { 
     Apple<int>::Banana freshBanana = someVar.returnsABanana(); //line 85 
     giveMonkey(freshBanana); //line 86 
    } 
}; 

내 문제는 컴파일러는 말한다되어

Carrot.h:85: error: expected ';' before 'freshBanana' 
Carrot.h:86: error: 'freshBanana' was not declared in this scope 

나는 완전한 이름을 사용하는이 중첩 된 클래스에 액세스 저를 허용 생각했다? 그것은 아마 얼굴에 나를 때려 눕힐 것이다. 그러나 내가 지구상에서 무엇을 여기에서 보지 않고 있냐??

+0

이전 버전의 gcc로 중첩 된 클래스에서 컴파일 문제가 발생했습니다 (gcc-3.4 사용). gcc-4.x에는 이러한 문제가 없으며이 코드는 작은 재 작업 후 잘 컴파일됩니다. 슬프게도, 아니요, –

답변

6

아마 코드에서하는 일이 아니겠습니까?

Apple<K>::Banana freshBanana = someVar.returnsABanana(); 

컴파일러는 이름이 형식인지 여부를 구문 분석하기 전에 알아야합니다. 이 경우 구문 분석시 어떤 유형이 K인지 알 수 없으므로 (중첩 된 클래스가없는 Apple<int>에 대한 전문화가 가능함). 따라서 Apple<K>::Banana은 유형이 아니라고 가정합니다. 하지만 표현식이므로 연산자 나 세미콜론 뒤에 연산자가 필요합니다.

당신은 typename를 삽입하여 문제를 해결할 수 있습니다 이름을 주장

typename Apple<K>::Banana freshBanana = someVar.returnsABanana(); 

는 유형이며, 컴파일러는 선언으로이 구문 분석 알고있다.

+0

. 나는 지나치게 단순화했지만. 위, 나는 선언한다 : typedef Apple IntyApple; 그래서 실제로 줄은 : IntyApple :: Banana freshBanana = someVar.returnsABanana(); 답변을 주셔서 감사합니다. – Nate

+0

비록 실제로 총을 뛰었습니다. typename에 대한 귀하의 제안은 실제로 제 실수를 멀리하게 만들었습니다 ... 아마도 나의 상황은 내가 깨닫고있는 것보다 더 복잡 할 것입니다. 고마워! – Nate

+0

@Nate, The Standard rules "클래스 템플릿의 범위 내에서 클래스 템플릿의 중첩 클래스의 규정되지 않은 이름을 참조하는 경우에는 해당 클래스를 포함하는 클래스의 이름으로 정규화 된 중첩 클래스의 이름과 같습니다 주형." (이것은 종속적이 될 것이다) typedef가 중첩 클래스가 아니기 때문에 여기서는 적용되지 않는다. 그것은 나에게 컴파일러 버그처럼 보일 것이다. 중첩 클래스의 경우 특정 템플릿 매개 변수에 대해 이러한 중첩 클래스를 특수화 할 수 있기 때문에 이러한 방식으로 종속적으로 만드는 것이 중요합니다. 그러나 typedef에 대해서는 그렇게 할 수 없습니다. –

관련 문제