본문 바로가기
개발개발/c++

c++ 템플릿

by 유잉유잉유잉 2024. 12. 22.
728x90

1. 템플릿  : 여러 자료형으로 사용할 수 있도록 할 수 있도록 미리 만들어 놓는 틀입니다.

컴파일 타임에 타입이 결정되어 컴파일은 느려지나 런타임 속도는 빨라집니다.

 

 

2. 함수 템플릿

// 클래스나 함수 상단에 선언. T라는 문자는 다른 문자열로 변경가능
template <typename T>

기본 구조는 위와 같고, 클래스나 함수의 상단에 선언하여 사용합니다.

 

#includ <iostream>

template <typename T>
T Add( T num1, T num2 )
{
	return num1 + num2;
}

int main()
{
	// 템플릿이 지정된 함수를 호출할 때 2가지 호출방법 
	// 1. 타입을 명시적으로 지정
	std::cout << Add<int>(1, 2)		<< std::endl;
    // 2. 인자에 들어간 데이터 타입으로 암시적으로 지정
	std::cout << Add(1.2f, 2.3f)	<< std::endl;

	return 0;
}

 

템플릿이 지정된 함수를 호출할 땐 2가지 호출 방법이 있습니다.

 1) 타입을 명시적으로 지정합니다.

 2) 인자에 들어간 데이터 타입으로 암시적으로 지정합니다.

// 1. 타입을 명시적으로 지정
std::cout << Add<int>(1, 2) << std::endl;
// 2. 인자에 들어간 데이터 타입으로 암시적으로 지정
std::cout << Add(1.2f, 2.3f) << std::endl;

 

 

 

여러개의 타입을 지정할 수 있으며, 디폴트 타입도 결정이 가능합니다.

// T2의 기본 템플릿 타입을 short로 지정
template <typename T1, typenme T2 = short>
struct FTest
{
	T test1;
    T2 test2;
    
public :
	void Output()
    {
    	std::cout << "typeid(T1).name() : " << typeid(T1).name() << std::endl;
    	std::cout << "typeid(T2).name() : " << typeid(T2).name() << std::endl;
    }
    
    // 구조체 전체에 지정한것 외에도 함수에 다른 템플릿 추가도 지정이 가능하다.
    // 당연히 구조체 전체에 지정한 템플릿을 사용할 수 있다.
    template <typename T3>
    void OutputTemplate()
    {
    	std::cout << "typeid(T1).name() : " << typeid(T1).name() << std::endl;
    	std::cout << "typeid(T2).name() : " << typeid(T2).name() << std::endl;
    	std::cout << "typeid(T3).name() : " << typeid(T2).name() << std::endl;
    }
}

int main()
{
	FTest<int, float> Test1;
	FTest<int> Test2;
    
	Test1.Output();
	Test2.Output();
	Test2.OutputTemplate<char>();
}

위 예제에서 볼 수 있듯이 구조체 전체에 지정한것 외에도 함수에 다른 템플릿을 추가로 지정할 수 있습니다.

그리고 당연히 해당 함수에선 구조체 전체에 지정한 템플릿을 사용할 수 있습니다.

위 내용은 클래스에서도 동일하게 적용됩니다.

 

 

▶️ typeid와 name(), hash_code()

typeid : 자료형이나 변수 또는 식을 입력받아 객체를 반환해주는 연산자입니다

name () : 타입의 이름을 반환합니다

hash_code() : 고유한 번호를 만들어 줍니다.

// 템플릿
template <typename T>
//int Add ( int num, int num2 )
T Add ( T num, T num2 )
{
	// typeid(T) : 명시적으로 어떻게 지정되었는지 알고 싶을 때 
	// typeid(T).hash_code: 고유한 번호를 만들어줌. 
	// typeid(T).name : 타입의 이름을 가져옴 
	std::cout << "typeid( T ).name() : " << typeid( T ).name () << std::endl;
	std::cout << "hash_code :" << typeid( T ).hash_code () << std::endl;

	return num + num2;
}

int main ()
{
	std::cout << Add <float> (1.2f, 2.3f) << std::endl;
    return 0;
}

 

 

▶️ 클래스에서 템플릿 사용

class CTest
{
public : 
	// 함수에만 템플릿 사용이 가능하다
    template <typename T>
    void Output( T t )
    {
    }    
}

 

 

 

‼️ 템플릿 사용시 주의사항

1. 템플릿을 사용하는 구조체나 클래스를 friend struct나 friend class로 사용시 템플릿의 선언도 함께 작성해야 합니다.

template <typename T>
struct FTest
{
	T test1;
}

template <typename T1, typename T2>
class CTest2
{}

class CTest
{
	template <typename T>
    friend struct FTest;
    
    template <typename T1, typename T2>
    firend class CTest2;
}

 

 

2. 템플릿 클래스 사용시 헤더에 선언과 구현을 동시에 해야합니다. 

그렇지 않으면 링크 에러가 날 수 있습니다.

 

 

 

 

▶️ 템플릿의 활용

class CObject
{
}

class CPlayer : public CObject
{
}

class CMonster : public CObject
{
}

class CItem : public CObject
{
}

template <typename T>
T* CreateObj ()
{
	T * obj = new T ;
	return obj;
}

void main()
{
	CPlayer * player	= CreateObj();
	CMonster * monster	= CreateObj();

	return 0;
}
728x90

'개발개발 > c++' 카테고리의 다른 글

STL과 벡터  (0) 2024.12.24
C++ 오퍼레이터, assert  (2) 2024.12.23
c++의 임시객체  (0) 2024.12.20
c++의 memset(), SetConsoleCursorPosition(), _kbhit(), _getch()  (1) 2024.12.19
c++의 동적배열 선언, 생성자에서 우선순위  (0) 2024.12.17

댓글