C++ 템플릿의 핵심 기능 (함수 템플릿과 클래스 템플릿)

함수 템플릿

함수 템플릿은 하나의 함수 정의로 다양한 데이터 타입에 대해 동작할 수 있도록 해주는 기능입니다. 이를 통해 코드 중복을 줄이고, 유연한 구현이 가능해집니다.

기본 예제: 값 교환

정수와 실수를 위한 별도의 스왑 함수를 작성하는 대신, 단일 템플릿으로 처리할 수 있습니다.

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

이 템플릿을 사용하면 컴파일러가 인자 타입에 따라 적절한 함수를 자동 생성합니다.

int x = 5, y = 10;
Swap(x, y);          // Swap<int>() 생성

double a = 3.14, b = 2.71;
Swap(a, b);          // Swap<double>() 생성

다중 타입 매개변수

여러 타입을 받는 함수 템플릿도 가능합니다.

template <typename T1, typename T2>
void Process(T1 val1, T2 val2) {
    std::cout << val1 << ", " << val2 << std::endl;
}

템플릿 오버로딩

매개변수 목록이나 타입 파라미터가 다르면 템플릿 오버로딩이 가능합니다.

template <typename T>
void Display(T a, T b) { /* ... */ }

template <typename T, typename U>
void Display(T a, U b) { /* ... */ }

템플릿 우선순위

호출 시 컴파일러는 다음 순서로 선택합니다:

  1. 정확히 일치하는 일반 함수
  2. 정확히 일치하는 템플릿 함수
  3. 형 변환 후 일치하는 일반 함수
  4. 모든 경우 실패 → 에러

클래스 템플릿

클래스 템플릿은 특정 타입에 맞춰 여러 클래스를 빠르게 생성할 수 있게 해줍니다.

기본 구문

template <typename T>
class Container {
    T data;
public:
    Container(T value) : data(value) {}
    T Get() const { return data; }
};

예시: 키-값 쌍 클래스

키와 값을 저장하는 Pair 클래스를 템플릿으로 정의합니다.

template <typename KeyType, typename ValueType>
class Pair {
private:
    KeyType key;
    ValueType value;

public:
    Pair(KeyType k, ValueType v) : key(k), value(v) {}

    bool operator<(const Pair& other) const {
        return value < other.value;
    }
};

// 사용 예
Pair<std::string, int> student("Alice", 25);
Pair<std::string, int> another("Bob", 28);

std::cout << (student < another) << std::endl;  // 출력: 1

멤버 함수 템플릿

클래스 내부의 멤버 함수도 템플릿으로 선언할 수 있습니다.

template <typename T>
class Helper {
public:
    template <typename U>
    void Print(U value) {
        std::cout << value << std::endl;
    }
};

Helper<int> h;
h.Print(42);         // Print<int>()
h.Print("hello");    // Print<const char*>()

비타입 매개변수

템플릿 파라미터로 크기 같은 상수도 사용 가능합니다.

template <typename T, size_t N>
class FixedArray {
    T data[N];
public:
    void Set(size_t idx, T val) { data[idx] = val; }
    T Get(size_t idx) const { return data[idx]; }
};

FixedArray<int, 10> arr;  // 고정 크기 배열

상속 관계

클래스 템플릿은 다른 템플릿, 일반 클래스, 또는 템플릿 클래스로부터 상속받을 수 있습니다.

// 템플릿에서 템플릿 상속
template <typename T>
class Base { };

template <typename T>
class Derived : public Base<T> { };

// 일반 클래스에서 템플릿 상속
class BaseClass { };
template <typename T>
class TemplateDerived : public BaseClass { };

친구 관계 (Friend)

템플릿 내부에서 일반 함수, 클래스, 함수 템플릿, 또는 다른 템플릿 클래스를 친구로 선언할 수 있습니다.

template <typename T>
class MyClass {
    friend void FriendFunction();                 // 일반 친구 함수
    friend class FriendClass;                     // 일반 친구 클래스
    friend template <typename U> void Func(U);   // 함수 템플릿 친구
};

정적 멤버 변수

템플릿 내부의 정적 멤버는 각 인스턴스마다 공유되며, 개별적으로 초기화되어야 합니다.

template <typename T>
class Counter {
private:
    static int instance_count;

public:
    Counter() { ++instance_count; }
    ~Counter() { --instance_count; }

    static void ShowCount() {
        std::cout << "Instances: " << instance_count << std::endl;
    }
};

// 정적 멤버 초기화
template <> int Counter<int>::instance_count = 0;
template <> int Counter<double>::instance_count = 0;

Counter<int> c1;
Counter<double> c2;
Counter<int>::ShowCount();  // 출력: 1
Counter<double>::ShowCount(); // 출력: 1

태그: template C++ function template class template generic programming

6월 20일 16:48에 게시됨