본문 바로가기

진리는어디에/C++

[C++] typename 키워드

들어가며

'Modern C++ Design'이라는 책에는 typename이라는 키워드가 종종 등장하곤 합니다. 물론 템플릿 파라메터로써만 사용되었다면 제가 이런 포스팅을 시작할 생각도 안했겠지요. template <class T>와 template <typename T>는 템플릿을 조금이라도 다루어 보았다면 모두 다 아실 정도의 수준이니까요.

오늘 제가 이 포스트에서 다루고자 하는 것은 템플릿 파라메터로써의 typename이 아니라, 이것이 타입인지 함수인지 구분이 안가는 모호한 문법 속에서 '이것은 타입이니 함수 처럼 다루지 마세요'라고 말하는 typename을 다뤄 보려고 합니다.

포스트에 설명 되어 있는 내용은 IBM 쪽에 올라온 문서를 기본으로 삼고 있습니다. 혹시나 원문이 궁금하신 분은 [여기]를 참고 하시면 됩니다.

typename 키워드

typename에 대한 장황한 설명을 하는 대신 예제를 먼저 살펴 보도록 하겠습니다. 아래의 코드는 typename을 언제 사용해야 하는지에 대한 간략한 예를 담고 있습니다.

template <class T>
class A {
    T::x(y);
    typedef char C;
    A::C d;
};

위의 코드 처럼 클래스를 하나 작성하고 컴파일을 해보십시오. 컴파일이 정상적으로 이루어 지나요? 물론 얄미운 에러 메시지들만 잔뜩 나올겁니다. 컴파일러가 판단하기에 위의 코드는 너무나도 모호한 부분이 많기 때문입니다(라고 해봐야 몇 줄안되는 코드 자체가 몇 줄 안되니 전혀 설득력이 없군요^^;). 그럼 지금 부터 하나씩 살펴 보도록 하겠습니다.

  1. 'T::x(y)'라는 표현이 너무 애매모호 합니다.
    컴파일러가 보기에 T::x(y)라는 것은 y라는 인자를 넘겨주는 class T의 static함수 x라고 생각 할 수도 있고, 혹은 T::x타입으로 선언되는 변수 y라고 생각 할 수도 있습니다.
    IBM의 문서에 따르자면 C++에서는 이것을 함수 호출로 해석한다고 합니다. 컴파일러가 이것을 변수 선언으로 해석하기 위해서는 typename 키워드를 앞에 붙여 줘야 합니다.

    실제 VC++7.0에서 위의 코드를 컴파일 한 결과 :
    • T::x는 변수로서 선언되지 않았다. 변수로 선언하려면 typename 키워드를 붙여야 한다라는 경고
    • T::x라는 함수에 리턴 값이 정의 되지 않았다. 디폴트 int로 셋팅 하겠다라는 에러
    • y라는 변수가 선언되지 않았다는 에러
    등등 주로 정상적지 못한 함수에 관련된 살벌한 에러들이 출력 되더군요. 물론 위의 클래스를 정상적으로 사용하기 위해서는 T가 되는 클래스에 x라는 타입이 정의되어 있어야만 할 것입니다.

  2. 'A::C d'는 문법 자체가 틀렸습니다...까지만 이해가 되었네요. 나머지는 저도 무슨 이야기인지 잘 몰라 원문을 그대로 올려 둡니다. 제가 영어 실력이 달리는 것인지..원래 못 알아 들을 말이 적혀 있는 것인지..
    The statement A::C d; is ill-formed. The class A also refers to A<T> and thus depends on a template parameter. You must add the keyword typename to the beginning of this declaration.
    없는 실력에 굳이 해석을 하자면 클래스 A역시 A<T>를 참조하고, 템플릿 파라메터에 의존적이기 때문에 typename 을 붙여 줘야 한다 라고 되어 있군요.

    1번과 같은 사례에 관련된 문서는 몇가지가 있으나 2번과 관련된 사례에 대한 것은 딱히 찾지 못했습니다. 혹시 알고 계시는 분이라면 댓글이나 트랙백을 달아 주시면 감사하겠습니다.

2 번과 관련된 사항을 제대로 해결하지 못한게 못내 아쉽네요. 왠지 제 블로그에 방문 하신분들을 낚은 것 같은 기분이 들기도 하구요.

부록 1. 같이 읽으면 좋은 글

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!