개발개발/c++

템플릿 - 비타입 인자, 템플릿 특수화, 템플릿 가변인자

유잉유잉유잉 2024. 12. 26. 23:47
728x90

 

▶️ 비타입 인자

  • 템플릿 매개변수 선언시, 상수를 사용한다고 선언하는것을 템플릿 비타입 인자라고 합니다.
  • 비타입 템플릿 인자는 상수로 취급됩니다.
  • 컴파일 타입에 어떤 값이 들어갈 지 결정되기 때문에 상수로 취급이 될 수 있는 것입니다.
template <int num>
void Print()
{
	std::cout << "num is : " << num << std::endl;
}

int main()
{
	Print<10>(); //

	return 0;
}

  • Print() 내부에서 num을 선언 및 초기화하지 않고 바로 사용이 가능합니다.
  • 상수처럼 바로 사용이 가능합니다. 

 

 

  • 템플릿 인자와 동일하게 여러개의 변수를 함께 선언할 수 있습니다.  타입과 비타입을 섞어서도 사용가능합니다.
  • 디폴트 인자값도 사용 가능합니다.
template <typename T, int number = 1000>
T * CreateArray()
{
	T * array = new T[number];
	return array;
}

 

 

 

▶️ 기존 함수의 인자 처리와, 템플릿의 인자 처리

런타임에 함수를 호출할 때 ( 인자 값을 전달 해줄 때 )

런타임에 스택 만듦 -> 해당 스택 공간에 값을 넘겨줌 -> 함수가 끝나면 스택을 정리 

 

템플릿은

런타임 시간에 이미 인자 값이 결정되어 있습니다. 결정이 되어 있는값으로 나머지를 진행합니다.

 

그렇기 때문에 많은 양을 처리할 경우 템플릿을 사용하는것이 더 빠른 처리 가능하다고 합니다.

 

 

 

 

▶️ 비타입 인자를 이용한 예제

/*
void Test()
{
	int count = 10;
	int arr[count]; // count가 상수가 아니라서 에러
    // 지역, 전역변수는 컴파일 타임에 생성할 사이즈를 지정해줘야 해서 에러가 나게 됨. 
    // 사이즈를 알아야 스택을 만들때 사이즈에 맞는 공간을 할당해줄 수 있기 때문.
}
*/

// 비타입은 상수처리 되기 때문에 가능합니다
template <int size>
int * CreateIntArr()
{
    int * arr = new int[size];
    return arr;
}

void main()
{
	int * arr = CreateIntArr<5>();
	return 0;
}

 

 

 

▶️ 템플릿 특수화 

특정 타입만 다른 방식으로 처리하기 위해 사용되는 문법 입니다.

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

void main()
{
	std::cout << Plus(1,2) << std::endl; // 3 : 정상출력 가능
	std::cout << Plus('a', 'b') << std::endl; // error C2110: '+': 두 포인터를 더할 수 없습니다. 
}

위 예제를 보면, Plus() 함수의 인자에 숫자 사용은 가능하나

문자열의 처리는 불가능합니다.

위 예제처럼 특정한 타입만 다른 방식으로 처리하기 위해 템플릿 특수화를 사용합니다.

 

template <typename T>
T Plus ( T num, T num2 )
{
	return num + num2 ;
}

// 템플릿 특수화
template <>
const char * Plus ( const char * num, const char * num2 )
{
    char result = new char [256];
    memset(result, 0, 256);
    
    strcpy_s( result, 256, num );
    strcat_s( result, 256, num2);
    
    return result;
 }
 
 void main()
 {
	std::cout << Plus( 1, 2 )	<< std::endl;
	std::cout << Plus( "aa", "bb" )	<< std::endl;
 }

위 예제에서는 인자가 const char * 타입일 때는 두번째 템플릿 Plus() 함수를 사용하고

그외엔 첫번째 템플릿 Plus()함수를 사용하게 됩니다.

 

 

 

▶️ 템플릿 가변인자 ( Variadic template )

템플릿 타입을 가변인자로 만들어서 타입을 가변적으로 받아올 수 있는 기능입니다.

// 재귀 함수 마지막에 호출할 함수
template <typename T>
T TestVariadic ( T param )
{
	return param;
}

// 재귀 함수를 활용한 예제
template <typename T, typename... Types>
T TestVariadic ( T Param, Types... Params )
{
	return Param + TestVariadic(Params...);
}

void main()
{
	std::cout << TestVariadic( 1, 2, 3 ) << std::endl;
}

  • 가변인자 템플릿의 인자 Types는 여러개의 타입을 나타냅니다.
  • 가변인자 함수 템플릿의 인자인 params안에는 여러개의 값이 있고, Parameter Pack이라 합니다.

 

 

▶️ Parameter Pack

가변인자 템플릿으로 받은 파라미터들을 일컫습니다.

 

 

첫번째 인자의 타입에 따라 

뒤에 float형의 파라미터들이 들어가도 

int형 타입의 결과가 나옵니다.

std::cout << TestVariadic(1, 2.2f, 3.1f) << std::endl;// 6 출력

 

 

비타입인자를 가변인자로도 사용 가능합니다

template <int... numbers>

 

 

 

728x90