둠치킨
코딩하는 둠치킨
둠치킨

블로그 메뉴

  • 홈
  • 분류 전체보기 (218)
    • BOJ (171)
      • 스택 (14)
      • 큐 (5)
      • 덱 (4)
      • 그래프 (30)
      • 배열 (8)
      • 재귀 (12)
      • 브루트 포스 (2)
      • 그리디 알고리즘 (7)
      • 다이내믹 프로그래밍 (13)
      • 백트래킹 (24)
      • 기하학 (4)
      • 트리 (4)
      • 구현 (14)
      • 수학 (3)
      • 맵 (1)
      • 다익스트라 (2)
      • 누적합 (5)
    • 자료구조 (14)
      • 스택 (3)
      • 큐 (5)
      • 덱 (2)
      • 그래프 (1)
      • 트리 (1)
      • 힙 (1)
      • 정렬 (1)
    • C++ (11)
      • 모두의코드 (2)
      • Effective C++ (3)
      • C++ STL (6)
    • 컴파일러 (1)
    • OS (17)
    • 컴퓨터 구조 (2)
    • Unreal Engine 5 (2)

공지사항

전체 방문자
오늘
어제

인기 글

최근 글

태그

  • BFS
  • boj
  • Bruteforce
  • C
  • C++
  • C++ STL
  • Cache Memory
  • deadlock
  • DFS
  • Effective C++
  • java
  • Mutex
  • next_permutation
  • os
  • Process
  • rotate
  • semaphore
  • spin lock
  • STL
  • STL C++
hELLO · Designed By 정상우.
둠치킨

코딩하는 둠치킨

C++/C++ STL

C++ STL (뇌를 자극하는) - 4장. 함수 템플릿 (Section 1)

2025. 7. 27. 12:15

※ 제가 개인적으로 공부하는 것이라 요약하거나 책에서 빠진 내용이 있을 수 있습니다 ※

Section 1. 함수 템플릿

템플릿은 두 종류가 있다

1. 함수 템플릿 : 여러 함수를 만들어내는 함수의 틀

2. 클래스 템플릿 : 여러 클래스를 만들어내는 클래스의 틀

예제

template<typename T>
void Print(T a, T b)
{
    cout << a << ", " << b << '\n';
}

int main()
{
    Print(10, 20);
    Print("ABC", "ad");
    Print<double>(0.123, 1.123); // 명시적 호출
}

템플릿 함수를 사용하면 컴파일러는 클라이언트(호출 측)의 함수 호출 인자 타입을 보고 템플릿 함수의 매개변수 타입을 결정하여 실제 함수인 템플릿 인스턴스 함수를 만들어낸다. (참고로 컴파일 타임에 이루어진다)

또한, 컴파일이 완료되면 함수 템플릿 (원본 함수 템플릿 자체)는 존재하지 않고 인스턴스화된 실제 함수들만 존재하게 된다.

 

템플릿도 함수처럼 여러 매개변수를 가질 수 있다.

template<typename T1, typename T2>
void Print(T1 a, T2, b)
{
    cout << a << ", " << b << '\n';
}

Print(10, "abc");

컴팡일러가 Print(10, 1.5)로 만드는 인스턴스는 다음과 같다

void Print<double , const char*>(double a, const char* b) { ... }

 

알고 갈 것 - class와 typename

템플릿임을 지정할 때 template<typename T>를 template<class T>로 사용할 수 있다. 현재 대부분의 컴파일러에서 두 형식 모두 지원. template<class T>는 C++ 표준화 이전부터 사용되던 형식. 표준화 이후 template<typename T>가 사용되지만 대부분 컴파일러 모두 둘다 지원.

 

Swap 템플릿 버전 예제

template<typename T>
void Swap(T &a, T &b)
{
    T temp = a;
    a = b;
    b = temp;
}

 

템플릿의 타입 객체 a, b로 어떠한 타입 객체든지 올 수 있을까??

정답은, 템플릿 함수 정의의 연산이 가능한 객체, 즉 인터페이스를 지원하는 객체라면 가능.

위 예제에서 해당 T temp =  a 문장에서는 복사 생성자를 호출하므로 복사 생성자(인터페이스)를 지원해야하며, a = b, b = temp 같은 문장에서는 대입 연산자를 호출하므로 대입 연산자(인터페이스)를 지원해야 한다.

 

그럼 반대로 만약 해당 기능이 없는데 사용하려 한다면 어떻게 될까? 우선 잘못된 선언 자체는 아무 문제가 없지만, 실제로 사용할 때 (즉, 사용해서 템플릿이 인스턴스화 될 때) 문제가 있으면 컴파일 에러가 발생한다.

 

배열 출력 함수 템플릿

template<typename T, int size>
void PrintArray(T* arr)
{
    for(int i=0; i<size; i++)
    {
    	cout << "[" << i << "]: " << arr[i] << '\n';
    }
}

int main()
{
    int arr[5] = {10, 20, 30, 40, 50};
    PrintArray<int, 5>(arr); // 명시적 호출
}

 

위 예제를 보면 매개변수로 타입뿐만 아니라 정수 등도 가능하다.

단, 클라 코드에서 PrintArray<int, 5>(arr1)처럼 명시적으로 호출한다. 이유는, 함수 인자가 arr라는 정보만을 제공하므로 5라는 템플릿 매개변수 인자를 클라 코드만으로 컴파일러가 추론할 수 없기 때문. 따라서 명시적으로 호출해 생성하게 된다. 부연 설명을 덧붙이자면 C 스타이 ㄹ배열은 그냥 메모리 덩어리라 .size() 같은 멤버 함수도 없고, 포인터인 T*로 받으면 배열인지조차도 모르기 때문에 명시적으로 배열 크기를 넘기는 것이다.

 

템플릿의 특수화 (Function Template Specialization)

말 그대로 특수화된 버전의 함수 템플릿을 제공하는 것.

class Point
{
    int x, y;
public:
    explicit Point(int _x = 0, int _y = 0) : x(_x), y(_y) { }
    void Print() const { cout << x << ',' << y << '\n'; }
};

template<typename T>
void Print(T a)
{
     cout << a << '\n';
}

int main()
{
    Point pt(2, 3);
    Print(pt); // 에러! cout << pt; 가 불가능하므로
}

Point 객체 pt는 cout의 << 연산이 가능한(인터페이스를 지원하는) 객체여야만 하는데 불가능하므로 인스턴스를 생성하지 못해 에러가 발생한다.

첫 번째 해결 방법은 Point 클래스에 << 연산자 오버로딩 함수를 추가하는 것. 하지만 소스코드로 지원하지 않는 라이브러리 상태 등 Point 클래스를 수정하지 못하는 상태라면 이 방법을 쓸 수 없다. 두 번째 해결 방법은 Point 객체만의 특수화된 함수 템플릿을 지원하는 것.

// 특수화 함수 템플릿
template< >
void Print(Point a) // 명시적 코드 : void Print<Point>(Point a)
{
    cout << "Print 특수화 버전: ";
    a.Print();
}

 

저작자표시 (새창열림)

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

C++ STL (뇌를 자극하는) - 4장. 함수 템플릿 (Section 2 ~ 3)  (0) 2025.07.28
C++ STL (뇌를 자극하는) - 3장. 함수 객체란  (1) 2025.07.25
C++ STL (뇌를 자극하는) - 2장. 함수 포인터  (2) 2025.07.24
C++ STL (뇌를 자극하는) - 1장. 연산자 오버로딩 (Section 6~7)  (0) 2025.07.23
C++ STL (뇌를 자극하는) - 1장. 연산자 오버로딩  (0) 2025.07.08
    'C++/C++ STL' 카테고리의 다른 글
    • C++ STL (뇌를 자극하는) - 4장. 함수 템플릿 (Section 2 ~ 3)
    • C++ STL (뇌를 자극하는) - 3장. 함수 객체란
    • C++ STL (뇌를 자극하는) - 2장. 함수 포인터
    • C++ STL (뇌를 자극하는) - 1장. 연산자 오버로딩 (Section 6~7)
    둠치킨
    둠치킨
    코딩 공부를 위한 코딩 블로그 기록 일기

    티스토리툴바