Minwoo Dev.

[C++] 템플릿(Template), 템플릿 특수화(Specialization) 본문

C++

[C++] 템플릿(Template), 템플릿 특수화(Specialization)

itisminu 2024. 7. 24. 15:42
728x90
반응형
SMALL

프로그램을 작성하다 보면 자료형에 따라 여러 개의 함수를 만들어야 하는 상황이 발생한다.

예를 들어서 덧셈 연산을 하는 프로그램이 있다고 하자.

#include<iostream>
using namespace std;


int Add(int n1, int n2){
    cout << "Add(int n1, int n2)" << endl;
    return n1 + n2;
}

double Add(double e1, double e2){
    cout << "double Add(double e1, double e2)" << endl;
    return e1 + e2;
}

int main(void){
    double a = 2.14;
    double b = 5.3;
    cout << Add(a, b) << endl;
    return 0;
}

 

실행 결과

 

 

위 코드에서는 double 타입의 두 변수를 사용하여 Add 함수를 호출하였다.

함수는 매개변수에 따라서 오버로딩이 가능하기에, 우리가 int형 변수 두 개의 덧셈을 계산하려면 위처럼 int 형의 Add 함수를 하나 더 작성해야한다.

 

 

 

이렇게 사용하려는 변수의 타입마다 함수를 하나씩 작성한다면 굉장히 번거로울 것이다.

 

이럴 때 우리는 템플릿(Template)을 사용하여 코드를 간단히 나타낼 수 있다.

 

템플릿(Template)

템플릿 이라는 단어는 액자, 틀 이라는 뜻을 가지고 있다.

  • 타입을 결정하지 않고 틀만 작성하여 나중에 컴파일러가 알아서 해당하는 타입의 함수를 만들어 사용하는 방식이다.

 

기본적인 형식은 아래와 같다.

template<typename T>
T 함수이름 (T 매개변수1, T 매개변수2, ...){
함수 내용
}

 

꼭 위의 형식이 아니더라도, 템플릿 변수 T에 의해 변수 타입이 정해지도록 하고싶은 부분에 T를 적어주면 된다.

 

사용할 때는 아래와 같은 형식으로 사용한다.

함수이름<타입>(매개변수, ...);

 

 

위의 Add 함수를 사용하여 에제 코드를 보이겠다.

 

#include<iostream>
using namespace std;

template<typename T>
T Add(T n1, T n2){
    return n1 + n2;
}

int main(void){
    double a = 2.14;
    double b = 5.3;
    cout << Add<double>(a, b) << endl;
    return 0;
}

 

실행 결과

 

Add<double>()을 사용하여 사용할 템플릿 변수가 double 타입이라는 것을 명시하였다.

 

 

+) 함수 호출에서 타입 명시의 생략

 

<> 안에 들어가는 타입을 생략할 수도 있다.

#include<iostream>
using namespace std;

template<typename T>
T Add(T n1, T n2){
    return n1 + n2;
}

int main(void){
    double a = 2.14;
    double b = 5.3;
    cout << Add(a, b) << endl; // <double> 생략!
    return 0;
}

 

실행 결과

 

 

 

템플릿 변수의 특수화

위와 같이 템플릿을 사용하여 함수를 만들 때, 어떤 타입은 일반적인 덧셈과 다르게 해야하는 상황이 있을 것이다.

예를 들어서 char* 형이 있다.

 

#include<iostream>
using namespace std;

template<typename T>
T Add(T n1, T n2){
    return n1 + n2;
}

int main(void){
    char *a = "I love ";
    char *b = "You.";
    cout << Add(a, b) << endl;
    return 0;
}

 

 

위 코드에서 보듯이, 문자열 두 개를 덧셈한다면 어떻게 되겠는가 ?

Java와 같은 언어들에서는 문자열의 덧셈이 이어지겠지만, C++에서는 문자열 두 개의 덧셈은 문자열이 하나로 합쳐지지 않는다.

 

실행 결과

 

 

따라서 우리는 템플릿 변수에서 char* 에 해당하는 부분만 편집해줘야 할 것이다.

이렇게 특정 자료형의 함수만 수정해주는 것을 템플릿 특수화라고 한다.

 

코드에서 char* 에 해당하는 함수만 따로 구현해준다면 템플릿 특수화를 진행한 것이다.

#include <iostream>
#include <cstring>
using namespace std;

template<typename T>
T Add(T n1, T n2){
    return n1 + n2;
}

template<> // 템플릿 특수화 부분
char* Add(char* n1, char* n2){
    char* result = new char[strlen(n1) + strlen(n2) + 1]; 
    strcpy(result, n1);
    strcat(result, n2); 
    return result;
}

int main(void){
    char a[] = "I love "; 
    char b[] = "You."; 
    char* result = Add(a, b);
    cout << result << endl;
    delete[] result; 
    return 0;
}

 

실행 결과

 

 

템플릿 특수화는 위처럼 template<>를 작성하고, 그 아래에 정해진 타입의 함수 내용을 수정하여 작성하면 된다.

위와 같은 경우에, char* 타입이라고 컴파일러가 인식하게 되면 특수화된 템플릿으로 만들어진 함수를 호출하게 될 것이다.

 

 

728x90
반응형
LIST