Home [C++] 템플릿과 템플릿 특수화
Post
Cancel

[C++] 템플릿과 템플릿 특수화

클래스와 함수 둘 다 템플릿 사용이 가능합니다.
사용 방법에 대해서는 큰 차이가 없음으로 함수를 기반으로 설명하였습니다.

추가로, 기본적인 템플릿 사용만을 설명하였습니다!

C#에서는 제너릭 C++에서는 템플릿이란 이름으로 비슷한 기능을 지원합니다

물론 기능적으로 비슷하다는 말이지 다른 점이 분명하니 MSDN에 정의된 내용을 참고하시면 좋을 것 같습니다.

 C++ 템플릿과 C# 제네릭의 차이점 - C# 프로그래밍 가이드

1. 함수 템플릿

함수에 템플릿을 사용하는 방법은 간단합니다.

**template**를 추가해주는 것인데요. 여기서 T는 자료형이 됩니다.

간혹,
template로 작성된 것을 볼 수 있는데 typename과 class는 이름만 다를 뿐 기능적으로 동일한 기능을 합니다.

그래도 차이점이 궁금하신 분들은 구글 검색을 통해 정보를 더 찾으실 수 있으십니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<iostream>

template<class T>
void FUNC(T& t)
{
	t += 100;
}

int main() 
{
	int num_int = 1;
	double num_double = 1.1;
	
	// FUNC(num_int);
	FUNC<int>(num_int);

	FUNC<double>(num_double);

	std::cout << num_int << std::endl;
	std::cout << num_double << std::endl;
}

// 출력 결과
101
101.1

FUNC(num_int)는 FUNC(num_int)로도 사용이 가능합니다.

FUNC(num_int)로 함수를 호출해도 내부적으로는 FUNC(num\_int)로 변환해서 사용하기 때문입니다.

2. 템플릿 특수화

위 코드에서 만약 std::string이 추가되었다면 어떻게 될까요??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<iostream>

template<class T>
void FUNC(T& t)
{
	t += 100;
}

int main() 
{
	int num_int = 1;
	double num_double = 1.1;
	std::string str = "s";

	FUNC<int>(num_int);
	FUNC<double>(num_double);
	FUNC<std::string>(str);

	std::cout << num_int << std::endl;
	std::cout << num_double << std::endl;
	std::cout << str << std::endl;
}

// 출력 결과
101
101.1
sd

std::string에 대해서 + 100이 아스키 코드로 인해 “d”로 변환되어서 “sd”라는 값으로 변경되었음을 확인할 수 있습니다.

물론 우리는 아스키 코드로 변환되기를 바라는 것이 아니기 때문에 std::string에서만큼 다르게 처리되면 좋을 것 같습니다.

이때 사용할 수 있는 문법이 템플릿 특수화입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<iostream>

// 함수 템플릿 원본
template<typename T>
void FUNC(T& t)
{
	t += 100;
}

// std::string에 대한 템플릿 특수화
template<>
void FUNC(std::string& t)
{
	t += " -> 100";
}

int main() 
{
	int num_int = 1;
	double num_double = 1.1;
	std::string str = "s";

	FUNC<int>(num_int);
	FUNC<double>(num_double);
	FUNC<std::string>(str);

	std::cout << num_int << std::endl;
	std::cout << num_double << std::endl;
	std::cout << str << std::endl;
}

// 출력 결과
101
101.1
s -> 100

std::string에 대한 템플릿 특수화로 인해 str 변수에 대한 출력 결과가 변경되었음을 확인할 수 있습니다

즉, 템플릿 특수화란 특정 자료형에 대해 다르게 처리하고 싶을 때 사용하는 문법이라 정의할 수 있습니다.

3. 부분 특수화

템플릿으로 두 개의 자료형을 받는데 그중 하나는 따로 정의하고 싶을 땐 부분 특수화를 통해 해결할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<iostream>

template<typename T, typename B>
void FUNC(T& t, B& b)
{
	t += b;
}

template<typename T>
void FUNC(T& t, int b)
{
	t *= b;
}

int main() 
{
	int num_int = 1;
	double num_double = 1.1;

	FUNC<int, double>(num_int, num_double);
	std::cout << num_int << std::endl;
	std::cout << num_double << std::endl;

	int num2 = 10;
	FUNC<int>(num2, 10);
	std::cout << num2 << std::endl;
}

// 출력 결과
2
1.1
100	// 부분 특수화로 *= 로 연산이 되었다
This post is licensed under CC BY 4.0 by the author.