728x90
반응형

C++ 템플릿(template) 문법: typenametemplate 키워드 사용 요약

C++ 템플릿 문법, 왜 헷갈릴까요?

  • C++ 템플릿을 사용하다 보면 typenametemplate 키워드의 정확한 사용법에서 자주 혼란을 겪게 됩니다.
  • 특히 중첩된 템플릿이나 종속 타입을 다룰 때는 문법적인 실수로 인해 컴파일 에러가 발생하기 쉬습니다.
  • 이 문서에서는 그런 혼동을 줄이기 위해 typenametemplate 키워드가 각각 언제 필요한지 간결한 표와 실습 예제를 통해 정리하였습니다.
  • 실전 코드 작성 중 만나는 다양한 상황에 대비해 유용하게 참고하시기 바랍니다.


1. typename vs template 요약표

  • 상황 예시 typename 필요 여부 template 키워드 필요 여부 설명
    종속 타입 이름 사용 typename T::value_type ✅ 필요 ❌ 불필요 T에 따라 달라지는 타입이므로 typename 필요
    비종속 타입 이름 사용 std::vector<int>::value_type ❌ 불필요 ❌ 불필요 T 같은 템플릿 인자에 의존하지 않음
    중첩된 템플릿 사용 T::template rebind<U>::other ✅ 필요 ✅ 필요 T가 템플릿이며, 내부에 또 다른 템플릿이 있을 경우
    템플릿이 아닌 멤버 접근 T::some_function() ❌ 불필요 ❌ 불필요 함수 호출이므로 typename, template 모두 불필요
    템플릿 멤버 함수 호출 ptr->template foo<T>() ❌ 불필요 ✅ 필요 foo가 템플릿 함수일 때 template 필요


2. 예시 비교

2.1. 올바른 사용

  • cpp

      template <typename T>
      void func() {
        typename T::value_type x;                  // 종속 타입 이름 → typename 필요
        typename T::template rebind<int>::other y; // 중첩 템플릿 → typename + template 필요
      }
    

2.2. 잘못된 사용

  • cpp

      template <typename T>
      void func() {
          T::value_type x;         // ❌ 컴파일 오류 → typename 필요
          T::rebind<int>::other y; // ❌ 컴파일 오류 → template 키워드 필요
      }
    


3. 기억 공식

  • T::X타입(type) 이면 → typename 필요

  • T::template Y<...> 처럼 템플릿 안의 템플릿(template)이면 → template 키워드 필요



4. 실습 예제 1: typename이 필요한 경우

  • cpp

      #include <iostream>
      #include <vector>
      
      template <typename T>
      void show_value_type() {
          // T::value_type은 종속 타입 이름 → typename 필요
          typename T::value_type val = 0;
     	 
          std::cout << "value_type: " << val << "\n";
      }
      
      int main() {
          show_value_type< std::vector<int> >();  // int로 출력됨
      }
    

4.1. typename을 생략한 잘못된 예

  • cpp

      // ❌ 컴파일 에러: 'T::value_type' is not a type
      T::value_type val = 0;
    


5. 실습 예제 2: template 키워드가 필요한 경우

  • cpp

      #include <iostream>
      
      template <typename T>
      struct Wrapper {
          template <typename U>
          struct Rebind {
              using type = Wrapper<U>;
          };
      };
      
      template <typename T>
      void use_rebind() {
          // T::template Rebind<U>::type → 중첩 템플릿 사용 → template 키워드 필요
          typename T::template Rebind<int>::type obj;
     	 
          std::cout << "Rebind succeeded\n";
      }
      
      int main() {
          use_rebind<Wrapper<double>>();
      }
    

5.1. template 키워드를 생략한 잘못된 예

  • cpp

      // ❌ 컴파일 에러: 'Rebind' is not a template
      typename T::Rebind<int>::type obj;
    


6. 실습 예제 3: 템플릿 멤버 함수 호출 시 template 필요

  • cpp

      #include <iostream>
      
      struct Example {
          template <typename T>
          void foo() {
              std::cout << "foo<T>() called\n";
          }
      };
      
      template <typename T>
      void call_foo(T* obj) {
          // 템플릿 멤버 함수 호출 시 → template 필요
          obj->template foo<int>();
      }
      
      int main() {
          Example e;
          call_foo(&e);
      }
    

6.1. template 키워드를 생략한 잘못된 예

  • cpp

      // ❌ 컴파일 에러: ‘foo’ is not a template
      obj->foo<int>();
    


7. 컴파일 실습 팁

  • 위 예제들은 하나씩 복사해서 주석을 바꿔보며 실습하면 효과적입니다.
  • GCC, Clang, MSVC 모두에서 동일한 문법 규칙이 적용됩니다.
  • C++ 표준은 typenametemplate을 생략하지 않도록 명시하고 있습니다.



  • 도움이 되셨으면 하단의 ❤️ 공감 버튼 부탁 드립니다. 감사합니다! 😄

728x90
반응형

+ Recent posts