2009-07-14 6 views
13
template<class T> 
class Set 
{ 
public: 
    void insert(const T& item); 
    void remove(const T& item); 
private: 
    std::list<T> rep; 
} 

template<typename T> 
void Set<T>::remove(const T& item) 
{ 
    typename std::list<T>::iterator it = // question here 
    std::find(rep.begin(),rep.end(),itme); 
    if(it!=rep.end()) rep.erase(it); 

} 

왜 remove()의 typename이 필요합니까?왜 여기에 typename이 필요합니까?

+0

아마 당신이 말하는 라인이 typename std :: list :: iterator it = std :: find (rep.begin(), rep.end(), itme)입니다. 그게 너의 의도라고 생각하기 때문에. – aem

답변

18

때문에 대답이 아닌 지역 정보 없이는 불가능할 수 불행한 구문 [*]은 C로부터 상속의 typename 필요 ++ C - 예를 들어 - (A * B;A 여부 명칭 형태에 있어서는 이것은 B을 포인터로 선언 한 것인가 아닌가) (이 경우는 곱셈식입니다. A부터 가능합니다. 비 로컬 정보없이 알 수있는 모든 것이 클래스의 인스턴스가 될 수 있습니다. 이상한 일을하기 위해 operator*을 오버로드 ;-).

대부분의 경우 컴파일러는 불분명 한 구문이 여전히 낮은 수준의 구문 분석기가 심볼 테이블 정보를 유지하는 상위 수준의 레이어에서 피드백을 필요로 함에도 불구하고 모호하지 않게하기 위해 필요한 비 로컬 정보를 가지고 있지만 ... 템플릿이 없으므로 (일반적으로는 아니지만 을 전문화하여 기술적으로 불법적 일 수 있으므로 해당 ::iterator이 유형 이름이 아닙니다 ;-).

[*] 내 의견뿐만 아니라 내부 사용을위한 새로운 프로그래밍 언어를 설계하고 구현하는 바쁜 켄 톰슨 (Ken Thompson)과 롭 파 이즈 (Rob Pikes)의 의견도 참고하시기 바랍니다. 대부분 C와 비슷하지만, C의 구문 설계 오류를 반복하지 않습니다. 새로운 언어 (예 : 좋은 구식 파스칼에서와 같이)는 구문에서 구문 분석을 사용하면 형식이 아닌 식별자를 구별 할 수 있습니다.

+1

반복자는 잠재적으로 정적 멤버 변수 일 수 있습니다. 그리고 기본적으로 컴파일러가 있다고 가정합니다. 따라서 컴파일러 오류입니다. –

+0

나는 그 언어가 "B ++"라고 불리는 지 여부를 확인하는 것이 상업적인 기밀성의 심각한 위반이 될 것이라고 생각합니까? ;-) –

+0

죄송합니다. 죽은 사람에게 다시 가져다 주시길 바랍니다. 그러나 8 년 후, 프로그래밍 언어에 대해 공개 할 수있는 정보가 더 있는지 궁금합니다. 나는 숨을 멈추지 않고있다. – Cebtenzzre

0

일반적으로 함수 정의에 대한 전체/부분 템플릿 지정을 정의 할 수 있으므로 클래스 선언에 typename/class T와 함수 정의가 모두 필요하다고 생각합니다. 예. 당신은 int, string에 대한 remove 함수를 전문화 할 수 있습니다. 따라서이 경우 컴파일러에게 "이것은 모든 유형의 일반 템플릿입니다"라고 말하면 나중에 정수 만 지정된 동일한 함수를 정의 할 수 있습니다. 일반적

+0

아,이 답변은 그 설명이 잘못되었습니다, 미안 해요! – DeusAduro

12

당신은 std::list<T>::iterator 사용 typename의 이야기 경우

유형 이름은 iterator 클래스 std::list<T> 내에서 정의 된 유형 명확히하기 위해 사용된다. typename이 없으면 std::list<T>::iterator은 정적 구성원으로 간주됩니다. typename은 템플릿 매개 변수에 의존하는 이름이 유형일 때마다 사용됩니다.

+0

+1 놀라운 설명! – AraK

1

'it'선언에 typename이 필요합니다. 그렇지 않으면 컴파일러는 표현식이 아닌 형식 선언이라는 것을 알기 때문입니다.

this page에 따르면 "형식을 참조하고 템플릿 매개 변수에 따라 한정된 이름을 가진 키워드는 typename을 사용하십시오."