Introduction
C++ 컴파일러가 템플릿을 인스턴스화 하는 규칙을 설명하고 있다. 이 규칙은 무척 많은 세부사항으로 이루어져 있다. 각 세부사항들을 알아 본다.
Content
1. 템플릿은 두 단계 룩업을 한다.
템플릿 코드는 템플릿을 파싱 할 때, 1차 룩업을 하고, 인스턴스화가 될 때 2차 룩업을 하여, 이름을 찾는다. 1차 룩업을 할 땐, 일반적인 룩업(영역에서 이름 찾기)과 ADL(인자 이름으로 이름 영역 끌고 오기)를 한다. 2차 룩업을 할 땐, 종속된 이름에서 룩업을 하고, 한정되지 않은 이름을 위해서 ADL이 추가로 수행 된다.
.. 이 말의 무슨 말이고 하면, 코드를 보자.
1차 룩업을 할 때(컴파일러가 템플릿 코드를 파싱 할 때)
지점 5, basefiled의 이름을 찾기 위해서 컴파일러가 분주히 찾지만, "종속 이름"에선 찾을 수 없기 때문에 그냥 패스 한다.
지점 6, notemplate_field의 이름을 찾기 위해서 컴파일러는 분주히 찾아 NoTemplate 클래스에 있는 이름인것을 기억한다.
2차 룩업을 할 때(템플릿 코드가 인스턴스화 될 때)
지점 5, 1차때 찾다 못찾았기에, 이제 다시 한번 찾기를 시도 하여, Base<bool>에서 이름을 찾는다.
ADL도 이러한 원리로 찾을 수 있는 건 찾아 두고, 인스턴스화 될 때 종속 이름에서 추가로 찾는다. 이렇게 2회에 걸쳐 룩업을 시도하는 이유는 "템플릿 파싱"에서 문제가 생길 수 있다고 생각한 C++ 위원회가 이렇게 하자고 결정했기 때문이다.
2. 템플릿 코드는 특별한 인스턴스화 지점(POI, point of instantiation)이 있다.
이제부터 그냥 POI 라고 하겠다. 템플릿 코드는 함수 템플릿과 클래스 템플릿 두개가 있다. 이 중 함수 템플릿 코드는 호출된 영역의 바로 바깥에 POI를 지정한다. .. 보다 코드가 좋으니 코드로 설명한다.
지점 1 : 이 구역은 불가능하다, 왜냐하면 g()가 아직 보이지않기 때문에, 인스턴스화 된다고 하여도 컴파일이 안된다.
지점 2,3 : 이 구역도 불가능하다. 왜냐하면 C++은 함수 내부에 함수를 정의 할수 없기 때문이다.
지점 4 : 이 구역은 모든게 다 보인다. 그러므로 여기가 POI이다.
그렇다면, 클래스 템플릿은 POI가 어떻게 설정 될까? 코드를 보자.
지점 4 : sizeof는 실체가 보여야 한다. 4 지점은 보이지 않는다. 그러므로 4는 불가능하다.
지점 2, 3 : 클래스 템플릿은 함수 내부에 정의/선언 될 수 없다. 이는 표준이다. 그러므로 불가능하다.
지점 1 : 그렇다. 클래스 템플릿 POI는 호출된 이름 영역 시작 전 바로 위에 자리 잡아진다.
3. 템플릿 코드는 포함 모델과 분리 모델이 있다.
클래스 템플릿에 다 정의해 두는 것을 포함 모델이라고 하고, 선언 따로 정의 따로 분리하는것을 분리 모델이라고 하는데, 포함모델의 경우 POI에 정의가 포함되어 있지만, 분리 모델에서는 POI가 선언과 정의로 분리 될 수 있다고 한다.(내가 책을 제대로 이해 한게 맞다면)
.. 위의 코드 처럼 export를 써서 분리 시킬 수 있다. 하지만 msvc 에서 컴파일 해보면, export 키워드가 예약 되어 있지만, 지원되지 않는다고 한다. 이 책의 초반에 "분리 모델"에 대해서 설명한 것이 더 자세하게 나와 있으므로, 생략한다.
단지 분리와 포함 모델이 있고, POI 생성도 분리 될 수 있다. 까지만 알면 될듯 싶다.(교양 인거 같네..)
4. 여러 번역 단위에 걸쳐서 룩업을 한다.
이번 장을 알기 위해서 컴파일러(msvc)에서 돌려 보았으나, export 키워드를 사용 할수 없기에, 컴파일이 되지 않는다. 책의 내용만 보고 이해 해야 되는 상황이라, 잘 정리가 되지 않는다.
요점은 템플릿 코드는 두번 이름 룩업을 한다. 첫번째는 템플릿 파싱시, 두번째는 템플릿 코드 인스턴스화 할 때, 이렇게이다.
첫번째 템플릿 파싱시, 종속되었으나, 한정되지 않은 함수는 일반 룩업이 되긴 하나, 오버로딩까지 해석하지 않는다. 두번째 인스턴스화 시점에는 종속되었고, 한정된 함수는 이름 룩업으로 찾고, 종속됬으나 한정되지 않은 이름은 ADL 법칙만을 사용하여 룩업한다.
하지만 위의 책의 내용은 요즘의 컴파일러에서 틀린 것이다. 틀렸다기 보다는 바뀌여야 한다. 가 맞을것 같다.
5. 1 ~ 4번까지의 종합 예제코드
실제로 예제코드로 컴파일 해보았고, 잘되었다(msvc, 아마도 g++ 도 될 것이다.) 하지만 export는 테스트 해볼 수 없으므로, .. 예제코드로 사용하지 않겠다.(. 필요한 사람은 책을...)
Digression
3단 논법을 최대한 구사 할려고 한다. 모든 것을 3단 논법으로 설명하는건 어렵지만, 되도록 3단 논법으로 구성 시키겠다. 3, 4, 5 번의 경우 export의 내용도 다루기 있기 때문에, 컴파일 하며 테스트 해보기가 힘들었다. 또한 책이 나온 시점(원서 기준)으로 부터 많은 시간이 지났기 때문에, Template 파싱이 좀 다르다는 것을 알았다.
그냥 교양 공부 했다는 샘 치는게 맞겠다.
'책 정리 > C++ Template' 카테고리의 다른 글
10장 인스턴스화 5부 : 명시적 인스턴스화 (0) | 2010.01.15 |
---|---|
10장 인스턴스화 4부 : 컴파일러가 템플릿 코드를 구현한 방식 (0) | 2010.01.13 |
10장 인스턴스화 2부 : 게으른 인스턴스화 (0) | 2010.01.03 |
10장 인스턴스화 1부 : 주문형 인스턴스화 (0) | 2010.01.03 |
9장, 템플릿에서의 이름 4부 : 클래스 템플릿의 상속 (360) | 2010.01.01 |
9장, 템플릿에서의 이름 3부 : 템플릿 파싱 (0) | 2009.12.31 |
9장, 템플릿에서의 이름 2부 : 템플릿에서 이름 룩업 규칙 (360) | 2009.12.30 |
9장, 템플릿에서의 이름 1부 : 템플릿에서 이름 평가 규칙 이해하기 (0) | 2009.12.29 |
8장, Part 4, 템플릿에서의 프렌드 : 이건 많이 다른데? (0) | 2009.07.29 |
8장, Part 3, 템플릿 인자 - 템플릿 인자의 다양한 설정 방법 (0) | 2009.07.25 |
최근댓글