template

2022. 4. 2. 02:47C++

템플릿을 활용하여 c++에서 자료형을 마음대로 가지고 놀 수 있다. 

구조체 -> 자료형을 사용자의 입맛대로 만드는 것.  (구조체와 클래스는 거의 유사)

템플릿은 함수 템플릿과 클래스 템플릿으로 나눌 수 있다. 

 

함수 템플릿

함수를 만들어 낼 때, 자료형을 정의하지 않고 두는 것.

c++에서는 오버로딩에 의해 아래와 같이 함수의 이름과 내용이 같은 코드가 성립한다. 

int sum(int a, int b){
	return a + b;
}
double sum(double a, double b){
	return a + b;
}

이는 매우 귀찮은 일이다. 같은 내용이더라도 전달받는 인자의 자료형이 달라지면, 새로 함수를 정의해야 한다 .

하지만 template을 사용하게 되면 아래와 같이 하나의 함수만 정의하면 된다 

template <typename T> //typename 대신 class를 사용해도 된다. 
T sum(T a, T b){
	return a + b;
}

만약 인자들의 자료형이 다를 경우엔 아래와 같다.  

template <typename T1, typename T2>  //typename 대신 class를 사용해도 된다. 
void printAll(T1 a, T2 b){
	cout << "T1: " << a <<endl;
    cout << "T2: " << b <<endl;
}

 

template 함수 예시 1.

#include <iostream>
#include <string>

using namespace std;

template <typename T>  //typename 대신 class를 사용해도 된다.  
T sum(T a, T b){
    return a + b;
}

int main(void){
    cout<<"int sum: ";
    cout<< sum<int>(3,4)<<endl;
    cout<< sum(3,4)<<endl;  // 템플릿 함수를 사용할 때, 어떤 자료형을 쓰는지 명확하게 표시하는 것이 좋다. 
    

    cout<<"string sum: ";
    cout<< sum<string>("hello","world")<<endl;
    // cout<< sum("hello", "world"); 오류 발생. error: invalid operands of types 'const char*' and 'const char*' to binary 'operator+'

    return 0;
}

 

template 함수 예시 2.

#include <iostream>
#include <string>

using namespace std;

template <typename T1, typename T2>  //typename 대신 class를 사용해도 된다. 
void printAll(T1 a, T2 b){
	cout << "T1: " << a <<endl;
    cout << "T2: " << b <<endl;
}

int main(void){
    printAll<string, int>("hello", 13);
    printAll("hello", 13);
 
    return 0;
}

 

예시 1에서 자료형을 명확하게 표시하지 않았더니 오류가 발생했다.

이는 컴퓨터가 "hello"와 "world"를 string 자료형이 아닌 const char*로 해석하였기 때문이다. 

Tip. C에서는 문자열의 반환값이 char지만, C++에서는 const char이다. 즉 아래의 코드는 에러를 발생시킨다. 

#inclue<iostream>
using namespace std;

void printAll(char* str){ //오류발생.  char을 const char으로 바꿔줘야 한다. 
	cout<<str<<endl;
}

int main(void)
{
	printAll("hello");	
	return 0;
}

 

 

템플릿 특수화

템플릿을 사용할때, 특수한 자료형에 대해서는 다른 처리를 하고 싶을 때 사용한다.

사용법은 아래와 같다.

template <typename T>	//typename 대신 class를 사용해도 된다. 
T sum(T a, T b){
   return a + b;
}
 
template<>
char * sum<char*> (char* s1, char* s2){
   char * str= "[char *]문자열은 더할 수 없습니다."; 
   return str; 
}

 

클래스 템플릿

클래스 내부의 멤버 변수의 타입에 대하여 template으로 선언할때 사용한다. 

유의할 점: 멤버 함수 클래스 외부에서 선언 할 때, 꼭 template 선언을 다시 해주어야 한다. 

클래스 템플릿은 객체를 생성할 때 타입을 정해준다. 

 

1. 멤버함수가 클래스 내에 선언되었을때

#include <iostream>
#include <string>
 
using namespace std;
 
template <typename T>
class Person{
private:
    string name;
    T height;
public:
    Person(string name, T height):name(name), height(height){}
 
    void printAll(){
        cout << "name : " << name << endl;
        cout << "number : " << height << endl;
    };
 
    void setName(string name){
        this->name = name;	//this->name은 멤버변수를 가르킨다.  name은 멤버함수내의 매개변수를 가르킨다.
    }
    void setNumber(T height){
        this->height = height;
    }
};
 
 
int main() {
//객체를 선언할때 <> 안에 template 의 타입을 넣는다.
    Person<int> p1("Mr. Dev C++", 173);
    Person<string> p2("Ms. Unix", "155cm");
 
    p1.printAll();
    p2.printAll();
    cout << endl;
    p1.setNumber(188);
    p2.setNumber("2m 10cm");
    cout << endl;
    p1.printAll();
    p2.printAll();
    return 0;
}

2. 멤버함수가 클래스 밖에 선언되었을 때

> 외부에 선언하는 멤버 함수 및 생성자 마다 template선언을 해주어야 한다.

#include <iostream>
#include <string>
 
using namespace std;
 
template <typename T>
class Person{
private:
    string name;
    T height;
public:
    Person(string name, T height);
    void printAll();
    void setName(string name);
    void setNumber(T height);
};
 
template <typename T>
Person<T>::Person(string name, T height):name(name), height(height){}
 
template <typename T>
void Person<T>::printAll(){
    cout << "name : " << name << endl;
    cout << "number : " << height << endl;
};
 
template <typename T>
void Person<T>::setName(string name){
    this->name = name;
}
 
template <typename T>
void Person<T>::setNumber(T height){
    this->height = height;
}
 
 
int main() {
//main 함수는 동일하다.
    Person<int> p1("Mr. Dev C++", 173);
    Person<string> p2("Ms. Unix", "155cm");
 
    p1.printAll();
    p2.printAll();
    cout << endl;
    p1.setNumber(188);
    p2.setNumber("2m 10cm");
    cout << endl;
    p1.printAll();
    p2.printAll();
    return 0;
}

 

 

 

 

 

 

 


출처: https://blockdmask.tistory.com/45 [개발자 지망생]

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

new와 delete  (0) 2022.04.03
malloc & free  (0) 2022.04.03
Reference  (0) 2022.04.03
call-by-reference & call-by-value  (0) 2022.04.02
pointer  (0) 2022.04.02