챕터 2-2 : 템플릿

언리얼 거토
|2024. 12. 31. 18:00

1. 함수 오버로딩

함수 오버로딩이란?

  • C++에서 동일한 이름의 함수를 정의할 수 있는 기능.
  • 함수 이름뿐 아니라 매개변수의 타입개수를 기준으로 구분.
  • C언어와 달리, C++은 함수 이름 + 매개변수 정보로 판단. <- 시그니쳐

함수 오버로딩이 되는 조건

  • 매개변수 타입이 다를 경우.
  • 매개변수 개수가 다를 경우.

예제: 매개변수 타입이 다른 경우

void display(int value);
void display(double value);
void display(string value);​
  • display(10) 호출 시: int 버전 실행.
  • display(3.14) 호출 시: double 버전 실행.
  • display("Hello!") 호출 시: string 버전 실행.

예제: 매개변수 개수가 다른 경우

void printSum(int a);
void printSum(int a, int b);
void printSum(int a, int b, int c);
  • printSum(10) 호출: 매개변수 1개 버전 실행.
  • printSum(10, 20) 호출: 매개변수 2개 버전 실행.
  • printSum(10, 20, 30) 호출: 매개변수 3개 버전 실행.

함수 오버로딩이 불가능한 경우

  • 반환 타입만 다를 경우: 컴파일 에러
int getValue();
double getValue(); // 반환 타입만 다름 -> 오류.
  • 디폴트 매개변수로 모호한 경우
void printMessage(string message = "Default");
void printMessage(); // 호출 모호 -> 오류.
  • 포인터와 배열로만 차이 나는 경우
void process(int* arr);
void process(int arr[]); // 포인터와 배열 구분 불가 -> 오류.

 

함수 오버로딩 호출 순서

 

1. 정확히 일치하는 타입을 먼저 찾음.

2. 암묵적 타입 변환이 가능한 함수로 이동.

 

예제: 호출 순서

#include <iostream>
using namespace std;

void process(int value) {
    cout << "(int) 호출" << value << endl;
}

void process(int value, int value2) {
    cout << "(int, int) 호출" << value * value2 << endl;
}

void process(float value) {
    cout << "(float) 호출" << value << endl;
}
 void process(float value, float value2) {
    cout << "(float, float) 호출" << value * value2 << endl;
}


int main() {

    process(10);    //(int) 호출
    process(3, 4.3);//(int, int) 호출

    return 0;
}

2. 템플릿 (Template)

템플릿이란?

  • 타입에 구애받지 않는 일반화된 코드 작성을 위한 문법.
  • 문법:
template <typename T>
  • T는 타입 파라미터로, 실제 타입으로 대체됨.
  • 함수나 클래스를 타입에 상관없이 정의 가능.

템플릿 함수 예제

  • 두 수 더하기
template <typename T>
T add(T x, T y) {
    return x + y;
}

int main() {
    cout << add(3, 4) << endl;         // 정수형 덧셈
    cout << add(3.3, 4.2) << endl;     // 실수형 덧셈
    return 0;
}
  • 최댓값 구하기
template <typename T>
T getMax(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    cout << getMax(10, 20) << endl;     // 정수형
    cout << getMax(3.5, 2.7) << endl;   // 실수형
    cout << getMax('a', 'z') << endl;   // 문자형
    return 0;
}
  • 배열 합 구하기
template <typename T>
T sumArray(T arr[], int size) {
    T sum = 0;
    for (int i = 0; i < size; ++i) {
        sum += arr[i];
    }
    return sum;
}

int main() {
    int intArr[] = {1, 2, 3, 4, 5};
    double doubleArr[] = {1.1, 2.2, 3.3, 4.4};
    cout << sumArray(intArr, 5) << endl;     // 정수형 배열
    cout << sumArray(doubleArr, 4) << endl;  // 실수형 배열
    return 0;
}

템플릿 활용 예제

  • 값 교환하기
template <typename T>
void swapValues(T &a, T &b) {
    T temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 10, y = 20;
    swapValues(x, y);  // 정수형
    cout << "x = " << x << ", y = " << y << endl;

    double p = 3.14, q = 2.71;
    swapValues(p, q);  // 실수형
    cout << "p = " << p << ", q = " << q << endl;
    return 0;
}
  • 값 비교하기
template <typename T>
bool isEqual(T a, T b) {
    return a == b;
}

int main() {
    cout << boolalpha;
    cout << isEqual(10, 10) << endl;   // 정수 비교
    cout << isEqual(3.5, 2.7) << endl;  // 실수 비교
    cout << isEqual('a', 'b') << endl;  // 문자 비교
    return 0;
}

템플릿 클래스 예제

  • 배열 관리 클래스
template <typename T>
class MyArray {
private:
    T* arr;
    int capacity;
    int size;

public:
    MyArray(int cap) : capacity(cap), size(0) {
        arr = new T[capacity];
    }

    ~MyArray() {
        delete[] arr;
    }

    void push(T value) {
        if (size < capacity) {
            arr[size] = value;
            size++;
        } else {
            cout << "배열이 가득 찼습니다!" << endl;
        }
    }

    void pop() {
        if (size > 0) {
            size--;
        } else {
            cout << "배열이 비어 있습니다!" << endl;
        }
    }

    void print() const {
        for (int i = 0; i < size; i++) {
            cout << arr[i] << " ";
        }
        cout << endl;
    }
};

int main() {
    MyArray<int> intArr(5);
    intArr.push(10);
    intArr.push(20);
    intArr.print();  // 정수형 배열

    MyArray<double> doubleArr(3);
    doubleArr.push(3.14);
    doubleArr.push(2.71);
    doubleArr.print();  // 실수형 배열
    return 0;
}

 

↓숙제: 오버로딩 된 함수 템플릿으로 변경하기

더보기

숙제 설명

  • 오버로딩된 함수를 템플릿으로 변경 해봅시다.
  • 우리는 타입이 동일한 두개의 인자를 받고 이를 더해서 반환하는 템플릿 함수를 구현해야 합니다.
  • 기존에 제공된 오버로딩 된 함수를 분석해서 하나의 템플릿 함수로 구현하시면 됩니다.
  • 템플릿 함수로 변경해야 할 오버로딩 된 함수
#include <iostream>

using namespace std;

//아래 3개의 함수를 하나의 템플릿 함수로 통합하세요
int add(int a, int b) {
    return a + b;
}

double add(double a, double b) {
    return a + b;
}

std::string add(const std::string& a, const std::string& b) {
    return a + b;
}


//아래 테스트 코드는 변역하지 마세요
int main() {
    // 정수 더하기
    cout << "3 + 5 = " << add(3, 5) << endl;

    // 실수 더하기
    cout << "2.5 + 4.3 = " << add(2.5, 4.3) << endl;

    // 문자열 합치기
    cout << "\"Hello, \" + \"World!\" = " << add(string("Hello, "), string("World!")) << endl;

    // 아래 코드는 컴파일 에러가 발생해야 함
    // cout << add(true, false) << endl;

    return 0;
}

 

답:

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

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

챕터 2-4: 객체지향적 설계  (1) 2025.01.03
챕터 2-3 : STL 기초  (1) 2025.01.02
챕터 2-1 : 자원 관리하기  (0) 2024.12.30
C++ 추가 자료  (1) 2024.12.27
챕터 1-3 : 객체지향 프로그래밍  (1) 2024.12.26