31. [C++] 템플릿

2024. 4. 24. 10:19[C++]/C++ 언어 기초

템플릿 : 함수의 기능은 있지만 자료형이 정해지지 않은 틀.

  • Java의 제네릭(Generic)같다는 생각이 들었다.
  • 타입이 없는 함수형태를 띄기 때문에 어떤 자료형을 입력하더라도 값 손실이 나는 것을 제외하고는 함수의 로직이 돌아간다.
using namespace std;
templete <typename T> //or templete <class T>

T Add(T num1, T num2){
	return num1 + num2;
}

int main(void)
{
	cout<<Add<int>(1, 2)<<endl;
	cout<<Add<double>(1.1, 1.9)<<endl;

	return 0;
}
templete <typename T> 혹은
templete <class T>형태로 템플릿 타입을 명시해줄 수 있다.
  • 템플릿은 일반 함수와 구분된다. = 템플릿 함수와 일반 함수의 이름이 같을 경우 다른 함수로 구분된다.
  • 또한, 여러 형태의 자료형을 쓸 수도 있다.
template <typename T, typename A>

T SumArray(A arr[], T len) {
	T sum = 0;
	for(int i = 0; i < len; i++)
		sum += arr[i];
	return sum;
}

 

 

함수 템플릿의 특수화

template<> void MySwap(double a, double b);

template<class T> 
void f(T t)
{
//나머지 자료형은 이 로직을 따르게 된다.
};

template<>
void f<char>(char c)
{
//char형으로 호출시 이 코드가 호출된다
}

template<> 
void f(double d)
{
//double형으로 호출시 이 코드가 호출된다
}
  • 만약 double 자료형을 사용할 때, 기존 템플릿에서 사용하는 함수 로직이 아닌 다른 로직을 사용할 경우 위와같은 식으로 재정의 해줄 수 있다.

 

클래스 템플릿

  • 클래스에도 마찬가지로 템플릿을 정의해줄 수 있다.
class Point{

private:
	int xpos, ypos;
public:
	Point(int x = 0, int y = 0) : xpos(x), ypos(y){}
	void ShowPosition() const{
		cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
	}
};



//templete 사용
templete <typename T>
class Point{

private:
	T xpos, ypos;
public:
	Point(T x = 0, T y = 0) : xpos(x), ypos(y){}
	void ShowPosition() const{
		cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
	}
};

 

  • T자리에 int를 호출하면 int가 들어가고, double형 좌표를 입력하면 T자리에 double이 들어간다.
  • 템플릿 함수를 호출할 때는 Arr<int>와 같은 자료형 명시가 생략이 가능하지만(Arr(1, 2)), 템플릿 클래스의 경우 반드시 자료형을 명시해야한다. Point<int> Point<double>
  • 클래스 템플릿 또한 특수화가 가능하다.

 

템플릿 인자

  • 템플릿 매개변수에는 변수가 올 수 있다.
  • 템플릿 매개변수는 디폴트 값 지정도 가능하다.
templete <typename T = int, int len = 7>
class SimpleFun{
private:
	T arr[len];
public:
	T& operator[](int idx)
    {
    	return arr[idx];
    }
};
  • SimpleFun<int, 5>를 입력하면 T에는 int형이 대입되고, len의 변수에는 5가 대입되어 상수처럼 쓸 수 있다.
  • SimpleFun<double, 7>도 마찬가지로 쓸 수 있다.
  • 값이 없으면 디폴트 값으로 대신한다.

 


13 - 1 실습

 

1번 문제

#include "stdafx.h"
#include <iostream>

using namespace std;
template <typename T>

void SwapData(T &xposition, T &yposition){
	T temp = xposition;
	xposition = yposition;
	yposition= temp;
}

class Point{

private:
	int xpos, ypos;
public:
	Point(int x = 0, int y = 0) : xpos(x), ypos(y){}
	void ShowPosition() const{
		cout<<'['<<xpos<<", "<<ypos<<']'<<endl;
	}
};

int main(void)
{

	Point pos1(2, 4);
	Point pos2(10, 20);

	pos1.ShowPosition();
	pos2.ShowPosition();

	SwapData(pos1, pos2);

	pos1.ShowPosition();
	pos2.ShowPosition();

	return 0;
}

 

2번 문제

#include "stdafx.h"
#include <iostream>

using namespace std;

template <typename T, typename A>
T SumArray(A arr[], T len) {
	T sum = 0;
	for(int i = 0; i < len; i++)
		sum += arr[i];
	return sum;
}

int main() {
	int len;
	cout << "길이 값: ";cin >> len;cout << endl;

	int arr[100];
	for(int i = 0; i < len; i++) {
		int get;
		cout << i+1 << "번 값: ";
		cin >> get;
		arr[i] = get; // 배열에 원소 할당
	}

	cout << "더한 값: " << SumArray(arr, len) << endl;

	return 0;
}

 

13-2 실습

#include "stdafx.h"
#include <iostream>

using namespace std;

template <typename T>
class SmartPtr
{
private:
	T * posptr;
public:
	SmartPtr(T *ptr):posptr(ptr){}
	T& operator*() const{return *posptr;}
	T* operator -> () const{return posptr;}
	~SmartPtr(){delete posptr;}
};

class Point{

private:
	int xpos, ypos;
public:
	Point(int x =0, int y=0):xpos(x), ypos(y){}
	void SetPos(int x, int y){
		xpos = x;
		ypos = y;
	}
	void ShowPosition() const{ cout<<'['<<xpos<<", "<<ypos<<']'<<endl; }
};


int main(void)
{
	SmartPtr<Point> sptr1(new Point(1, 2));
	SmartPtr<Point> sptr2(new Point(3, 4));
	sptr1 -> ShowPosition();
	sptr2 -> ShowPosition();

	sptr1 -> SetPos(10, 20);
	sptr2 -> SetPos(30, 40);
	sptr1 -> ShowPosition();
	sptr2 -> ShowPosition();

	return 0;
}
반응형