독서노트Effective_C++_조항42:typename의 이중적 의미 이해

3741 단어 effective
말 그대로 typename에는 이중적인 의미가 있다.네가 template를 사용한 적이 있다면, 첫 번째 의미는 반드시 알 것이다. 그것이 바로 템플릿을 성명할 때, 우리는 이렇게 쓸 수 있다.
 template  
이렇게 써도 돼요.
 template  
이 두 가지 쓰기는 아무런 차이가 없다. 모두 표시 T는 스텔스 인터페이스에 부합되는 모든 종류가 될 수 있다. 시스템의 미리 정의된 종류를 포함하고 사용자 정의 종류도 포함한다.
 
typename의 두 번째 의미는 컴파일러에 의존하기 때문에 다음 예를 보십시오.
 1 class SampleClass
 2 {
 3 public:
 4     typedef int MyInt;
 5 // static const int MyInt = 3;
 6 };
 7 
 8 int main()
 9 {
10     SampleClass::MyInt *b = new int(3); //         
11 }

MyInt는 SampleClass 내의 재정의에서 유래한 것으로 MyInt는 int와 같기 때문에main 함수에서 실질적으로 int*b=new int(3)이지만 어떤 컴파일러는 error를 보고한다. 이것은 컴파일러가 이 코드를 만나면 잘못된 뜻을 가지기 때문이다. 왜냐하면 MyInt를 SampleClass의 정적 대상으로 볼 수 있기 때문이다(프로그램이 주석한 코드를 볼 수 있는 곳). 그러면 정적 대상 b가 된다.이런'견해'는 다소 불가사의하지만, 일부 컴파일러에서는 유형이 아닌 정적 변수로 우선적으로 여긴다.이 이의성을 해결하기 위해서 앞에 typename을 붙이면 컴파일러가 정적 변수가 아닌 하나의 유형으로 간주하도록 강요할 수 있다.이런 SampleClass::MyInt 또는 책에 든 T:::constiterator는 클래스에 정의된 이름입니다. 이런 이름은 dependent names(중첩 종속 이름)라고 합니다. 모든 dependent names는 이의성을 잠재하고 있습니다. 이의성을 없애기 위해 앞에 typename를 붙여서 typename T::const 로 바꿉니다.iterator, typename Sample Class: My Int, 이렇게 하면 정확해 보이지만 아무리 해도 편집할 수 없는 코드 문제를 해결할 수 있습니다.
typename을 사용하는 두 가지 특례가 있는데 하나는 계승할 때 다음과 같다.
1 class A: public B::NestedClass{}; //   
2 class A: public typename B::NextedClass(){}; //   

XXX 클래스를 계승할 때, 이 클래스 이름이 dependent names일지라도 typename를 사용하지 마십시오. 컴파일러가 정적 구성원으로 번역하지 않기 때문입니다. (계승된 클래스는 반드시 유형입니다.)
 
또 다른 특례는 함수를 구성할 때 구성 구성원 목록에 대해 다음과 같다.
1 A(): B::NestedClass(){} //   
2 A(): typename B::NestedClass(){} //   

이때 컴파일러도 정적 대상으로 간주하지 않는다. 정적 대상은 구성원 초기화 목록과 같은 초기화 형식을 지원하지 않기 때문에 이때의 typename은 오히려 컴파일러에 의해 BUG로 여겨진다.
 
마지막으로 요약:
1. template 매개 변수를 설명할 때 접두사 키워드class와 typename는 서로 바꿀 수 있습니다
2. 키워드 typename을 사용하여 네스트된 종속 유형 이름을 식별합니다.base class lists 또는 member initialization list에서 typename을 사용할 수 없습니다.
 
 

좋은 웹페이지 즐겨찾기