• 티스토리 홈
starryeye
  • 프로필사진
    starryeye
    • 분류 전체보기 (189)
      • C++ (17)
      • Java (24)
      • OOP (5)
      • Spring Reactive Stack (12)
        • Reactive Streams (3)
        • Netty (4)
        • Reactor (1)
        • Webflux (3)
        • DB, Cache 연동 (1)
      • Spring (90)
        • Core (17)
        • MVC (33)
        • Client (2)
        • Security (4)
        • DB, Cache 연동 (33)
      • DataBase (12)
        • RDBMS (2)
        • NoSQL (10)
      • Message Broker (6)
      • Web (4)
      • Network (4)
      • 대규모 시스템 설계 (15)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • [C++] template
        2022년 08월 14일
        • starryeye
        • 작성자
        • 2022.08.14.:56
        반응형

        다 아는 내용이지만 다시 정리 해보자..

         

        C++의 템플릿

        사용자가 원하는 타입을 넣어주면 알아서 코드를 찍어내는 틀이다.

         

         

        class template

        클래스 템플릿

        std::vector와 비슷한 역할을 하는 myVector 라는 클래스로 설명하겠다..

         

        template <typename T>
        class myVector {
            T* data;
            int capacity;
            ...
        }

        위 코드에서 template <typename T> 라는 부분은.. 템플릿 문장이다.

        아래에 정의되는 myVector라는 클래스에 대해 템플릿을 정의하고,

        템플릿 인자로 T를 받게 되며, T는 반드시 어떤 타입 이름임을 명시한다.

         

        template <class T>

        위 처럼 쓰기도 하는데 template <typename T> 와 기능상 정확히 동일하다.

        과거 C++에서는 template 인자로 class 키워드를 사용했지만,

        혼동을 막기위해 typename 키워드를 만들었고 하위 호환성을 위해 남겨두었다.

        -> typename 키워드를 사용하자.

         

        그러면 계속해서 알아보자..

         

         

        class template instantiation

        클래스 템플릿 인스턴스화

        myVector<int> v1;
        myVector<std::string> v2; 

        위와 같이 사용하면 되며..

        myVector 의 템플릿 인자에 타입(int, std::string)을 전달하면,

        컴파일러는 타입을 보고 실제 코드를 생성한다.

        (int의 경우 T 대신 int가 들어간 코드가 생성된다.)

         

        이렇게 클래스 템플릿에 인자(타입)을 전달하여 실제 코드가 생성되는 것을

        클래스 템플릿 인스턴스화 라고 부른다.

         

         

        template specialization

        템플릿 특수화

         

        템플릿 타입에 따라 다르게 처리하고 싶을 때는 어떻게 할까..

         

        아래와 같이 정의하면 된다.

        //일반적인 경우
        template <typename A, typename B, typename C>
        class temp {
            ...
        };
        
        
        //A와 C가 각각 int 타입, double 타입일 경우엔 따로 처리하고 싶어
        template <typename B>
        class temp<int, B, double> {
            ...
        };
        
        
        //A, B, C가 모두 int 타입일 경우엔 이렇게 처리하고 싶어..
        template <>
        class temp<int, int, int> {
            ...
        };

        마지막 template을 보면 template <> 이라고 되어있다.

        전달하는 템플릿 인자가 없더라도 template<> 이라고 남겨줘야한다.

         

        타입에 따라.. 템플릿을 모두 작성하려면 번거롭고 힘들 수도 있다..

        아래 포스팅을 보고 생각해보자.

        https://starryeye.tistory.com/50?category=1090077 

         

         

        Function template

        함수 템플릿

        이번에는 함수 단위로 사용할 수 있는 템플릿이다.

         

        template <typename T>
        T findMin(T& a, T& b) {
            if(a > b)
                return b;
            else
                return a;
        }
        
        int main() {
            int a = 1;
            int b = 2;
            
            int c = findMin(a, b);
            
            cout << c << endl;
        }

        위 코드의 findMin 함수도 인스턴스화 되기 전까지는 컴파일 시점에 아무런 코드로 변환 되지 않는다.

         

        함수 템플릿은

        클래스 템플릿을 인스턴스화 할때 처럼

        findMin<int>(a, b); 를 안해줘도 되는데..

        이는 a, b 타입을 보고 컴파일러가 findMin<int>(a, b); 로 인스턴스화 해주기 때문이다.

         

        <참고>

        아래와 같이 템플릿이 정의 되어있을 경우에는 <> 를 생략 할 수 없다.

        num을 non-type template arguments(타입이 아닌 템플릿 인자) 라 부른다.

        template <typename T, int num>
        T add_num(T t) {
            return t + num;
        }
        
        int main() {
            int x = 1;
            cout << add_num<int, 10>(x) << endl;
        }

        템플릿 인자로 전달할 수 있는 타입..

        bool, char, int, long 등 (float, double 제외)

        포인터 타입, enum, std::nullptr_t

         

        그런데.. 함수 파라미터에 티폴트 인자를 넣어줄 수 있듯이..

        템플릿에도 동일한 기능이 제공된다.

        template <typename T, int num = 10>
        T add_num(T t) {
            ...
        }

        위와 같이 해놓으면 add_num(1); 처럼 <>을 생략 가능하다.

        (컴파일러가 deduction 해줌)

         

         

        이제 함수 템플릿의 대표적인 예시를 한번 보고 끝내자..

         

        대표적 예시

        std::array<int, 3> arr = {1, 2, 3};

        std::array를 사용할 때, array의 크기를 템플릿 인자를 통해 전달 할 수 있다.

        (컴파일 시점에 배열 크기 정해짐, 런타임시점에 동적으로 크기가 할당되는 것이 아니다) 

        -> 그리고.. 해당 타입은 std::array가 아닌.. std::array<int, 3> 이라는 타입이다.

        -> 그러면 쓰기 힘들겠다..

        template <typename T>
        void addArray(T& arr) {
            for(int i = 0; i < arr.size(); i++) {
                arr[i]++;
            }
        }

        -> 위와 같이 이 역시.. template으로 만들어

        -> std::array<int, 3>을 위한 함수, std::array<int, 5>을 위한 함수를 따로 만들 필요가 없다.

         

        <주의>

        template <typename T>
        std::size_t retSize(T& t) {
            return t.size();    
        }

        참고로 위와 같은 템플릿이 있을 때,

        T라는 타입이 class가 아니거나..

        size()라는 함수가 정의 되지않은 class 이면..

        당연하게도.. 컴파일 오류가 난다.

        (컴파일 시점에 템플릿 인스턴스화할 때 문제가 발생하기 때문..)

         

         

        대표적 예시 2

        algorithm 헤더에 정의되어 있는

        sort 함수이다.

        template <class RandomAccessIterator, class Compare>
        void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

        더 자세한 정의 : https://www.cplusplus.com/reference/algorithm/sort/

        sort() 함수 세번째 파라미터로

        개발자가 구현한 static 비교 함수 또는 greater<>() 또는 less<>()를

        함수 템플릿 class Compare 인자로 넘겨주면..

        interator first, last 범위내 원소들이 정렬 될 수 있도록 한다.

         

        반응형

        'C++' 카테고리의 다른 글

        [Modern C++ 정리] Temporary 2  (0) 2022.09.05
        [Modern C++ 정리] Temporary 1  (0) 2022.09.05
        [Effective Modern C++] 항목 8  (0) 2022.08.14
        [Effective Modern C++] 항목 5  (0) 2022.08.14
        [C++] move와 copy  (0) 2022.07.15
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바