전체 코드

1. 함수 템플릿 (Function Template)

📌 기존 문제점

void Print(int a) { cout << a << endl; }
void Print(float a) { cout << a << endl; }
void Print(double a) { cout << a << endl; }
void Print(const char* a) { cout << a << endl; }

위처럼 자료형마다 Print 함수를 오버로딩하는 것은 코드 중복이 많아지는 비효율적인 방식입니다.

📌 함수 템플릿 활용

#include <iostream>
using namespace std;

template<typename T>  // 템플릿 정의 (T는 타입 매개변수)
void Print(T a) {
    cout << a << endl;
}

int main() {
    Print<int>(50);       // 명시적 타입 지정 가능
    Print(50.0f);         // 자동으로 float 타입으로 결정
    Print(50.0);          // double 타입으로 결정
    Print("Hello World"); // const char* 타입으로 결정

    return 0;
}

✅ 코드 설명

  • template<typename T>를 선언하여 T를 다양한 타입으로 변경 가능하게 합니다.
  • Print<int>(50);Tint로 해석하여 실행됩니다.
  • Print(50.0f);Tfloat로 해석하여 실행됩니다.

2. 함수 템플릿 특수화 (Function Template Specialization)

특정 타입에 대해 일반적인 템플릿과 다르게 동작해야 할 때 사용합니다.

📌 일반 템플릿과 특수화 예제

#include <iostream>
using namespace std;

class Knight {
public:
    int _hp = 100;
};

// 기본 템플릿 (모든 타입에 대해 동작)
template<typename T>
void Print(T a) {
    cout << a << endl;
}

// 특수화 템플릿 (Knight 타입에 대해 동작)
template<>
void Print(Knight a) {
    cout << "Knight 특수화된 템플릿 호출" << endl;
    cout << "HP: " << a._hp << endl;
}

int main() {
    Print(50);
    Print(3.14);
    Print("Hello Template!");

    Knight k;
    Print(k);  // 템플릿 특수화가 호출됨

    return 0;
}

✅ 코드 설명

  • template<>를 사용하여 Knight 클래스에 대한 특수화 버전을 정의했습니다.
  • Print(k);를 실행하면 일반적인 템플릿이 아니라 특수화된 템플릿이 호출됩니다.

3. 여러 개의 타입을 받는 템플릿

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

int main() {
    Print("Number:", 100); // "Number: 100" 출력
    Print(3.14, 42);       // "3.14 42" 출력

    return 0;
}

✅ 코드 설명

  • template<typename T1, typename T2>를 사용하여 서로 다른 두 타입의 매개변수를 받을 수 있습니다.

4. 함수 템플릿의 반환값

템플릿을 이용하여 반환 타입도 자동으로 결정할 수 있습니다.

template<typename T>
T Add(T a, T b) {
    return a + b;
}

int main() {
    int result1 = Add(1, 2);      // int 타입으로 처리
    float result2 = Add(1.5f, 2.3f); // float 타입으로 처리

    cout << result1 << endl;
    cout << result2 << endl;

    return 0;
}

✅ 코드 설명

  • Add<int>(1, 2)int 타입으로 해석됨.
  • Add(1.5f, 2.3f)float 타입으로 해석됨.

5. 클래스 템플릿 (Class Template)

함수뿐만 아니라 클래스도 템플릿화하여 일반화된 코드를 작성할 수 있습니다.

📌 클래스 템플릿 기본 예제

template<typename T>
class RandomBox {
public:
    T GetRandomData() {
        int idx = rand() % 10;
        return _data[idx];
    }
public:
    T _data[10]; // 크기 10짜리 배열
};

int main() {
    srand(static_cast<unsigned int>(time(nullptr)));

    RandomBox<int> rb1;
    for (int i = 0; i < 10; i++)
        rb1._data[i] = i;

    int value1 = rb1.GetRandomData();
    cout << "랜덤 값 (int): " << value1 << endl;

    RandomBox<float> rb2;
    for (int i = 0; i < 10; i++)
        rb2._data[i] = i + 0.5f;

    float value2 = rb2.GetRandomData();
    cout << "랜덤 값 (float): " << value2 << endl;

    return 0;
}

✅ 코드 설명

  • template<typename T>를 사용하여 데이터 타입을 변경할 수 있는 클래스를 생성합니다.
  • RandomBox<int>int 타입의 데이터 저장.
  • RandomBox<float>float 타입의 데이터 저장.

6. 클래스 템플릿 특수화 (Class Template Specialization)

특정 타입에 대해 클래스 템플릿을 다르게 동작하도록 할 때 사용합니다.

📌 특정 타입(double)에 대한 특수화

template<typename T, int SIZE>
class RandomBox {
public:
    T GetRandomData() {
        int idx = rand() % SIZE;
        return _data[idx];
    }
public:
    T _data[SIZE];
};

// 특수화: double 타입에 대해 별도로 정의
template<int SIZE>
class RandomBox<double, SIZE> {
public:
    double GetRandomData() {
        cout << "RandomBox double 특수화된 템플릿 호출" << endl;
        int idx = rand() % SIZE;
        return _data[idx];
    }
public:
    double _data[SIZE];
};

int main() {
    RandomBox<int, 10> rb1;
    RandomBox<double, 10> rb2;

    cout << rb2.GetRandomData() << endl; // 특수화된 함수 호출

    return 0;
}

✅ 코드 설명

  • template<typename T, int SIZE> 기본 템플릿을 정의합니다.
  • template<int SIZE>double 타입에 대한 특수화를 진행합니다.
  • RandomBox<double, 10>을 호출하면 특수화된 GetRandomData()가 실행됩니다.

7. 템플릿의 활용: 다양한 자료형을 처리하는 컨테이너

template<typename T>
class Container {
public:
    Container(T value) : _value(value) {}

    void PrintValue() {
        cout << "저장된 값: " << _value << endl;
    }

private:
    T _value;
};

int main() {
    Container<int> intContainer(10);
    Container<string> strContainer("Hello Template");

    intContainer.PrintValue();
    strContainer.PrintValue();

    return 0;
}

✅ 코드 설명

  • Container<int> 객체는 int 값을 저장.
  • Container<string> 객체는 string 값을 저장.
  • 템플릿을 이용하여 다양한 타입을 처리할 수 있는 컨테이너를 생성.

profile
李家네_공부방

0개의 댓글