[C++기초] 11. 템플릿 프로그래밍

INDEX

  1. 함수 템플릿
  2. 클래스 템플릿
  3. 클래스 템플릿 트릭
  4. 두 개의 템플릿 매개변수
  5. 템플릿 특수화
  6. 템플릿 프로그램의 장점과 단점

함수 템플릿

템플릿이란?

템플릿 함수 예시

template<typename T> //또는 template<class T>
T Add(T a, T b)
{
    return a + b;
}

int main()
{
    std::cout<<Add<int>(3,10)<<std::endl;
    std::cout<<Add<float>(3.14f,10.14f)<<std::endl;
    return 0;
}

함수 템플릿

typename vs class

클래스 템플릿

클래스도 템플릿으로 만들 수 있을까?

클래스 템플릿 트릭

벡터를 사용하고 싶은데, 벡터가 늘어나지 않았으면 좋겠다!

//FixedVector.h

template<typeName T, size_t N>
class FixedVector
{
public:
	//public 메서드들
private:
	T mArray[N];
};
//main.cpp

FixedVector<int, 16> numbers;

더 자세한 예시

//FixedVector.h

#pragma once
namespace samples
{
	//N은 size_t형이어야 함
	template<typename T, size_t N>
	class FixedVector
	{
	public:
		FixedVector();
		bool Add(const T& data);
		size_t GetSize() const;
		size_t GetCapacity() const;
		//enum 트릭이 없다!
	private:
		size_t mSize;
		// mArray를 정적으로 만듦 (new를 안 쓰는 것은 언제나 좋다)
		T mArray[N];
	};
	// 구현부 ~
	// 생성자
	template<typename T, size_t N>
	FixedVector<T, N>::FixedVector()
	: mSize(0)
	{
	}
	
	template<typename T, size_t N>
	size_t FixedVector<T, N>::GetSize() const
	{
		return mSize;
	}
	
	template<typename T, size_t N>
	size_t FixedVector<T, N>::GetCapacity() const
	{
		return N;
	}
	
	template<typename T, size_t N>
	bool FixedVector<T, N>::Add(const T& data)
	{
	if(mSize>= N)
	{
		//여기에 assert 넣어도 됨.
		return false;
	}
	mArray[mSize++] = data;
	return true;
	}
	// ~ 구현부
}
//main.cpp

#include<iostream>
#include"FixedVector.h"
#include"FixedVectorExample.h"
using namespace std;
namespace samples
{
	void FixedVectorExample()
	{
		//기본 자료형을 넣을 때
		FixedVector<int, 3> socres;
		scores.Add(10);
		scores.Add(50);
		cout<<"scores - <Size, Capacity> : " << "<" << scores.GetSize() << ", " << scores.GetCapacity() << ">" << endl;
		
		//개채를 넣을 때
		FixedVector<IntVector, 5> intVectors;
		intVectors.Add(IntVector(2,5));
		intVectors.Add(IntVector(4,30));
		intVectors.Add(IntVector(22,3));
		cout<<"scores - <Size, Capacity> : " << "<" << intVectors.GetSize() << ", " << intVectors.GetCapacity() << ">" << endl;
		
		//개채 포인터를 넣을 때
		FixedVector<IntVector*, 4> intVectors2;
		IntVector* intVector = new IntVector(3, 2);
		intVectors2.Add(intVector);
		cout<<"scores - <Size, Capacity> : " << "<" << intVectors2.GetSize() << ", " << intVectors2.GetCapacity() << ">" << endl;
		delete intVector;
	}
}

두 개의 템플릿 매개변수

pair같은걸 만들어보자

//MyPair.h

template<typename T>
class MyPair
{
public:
	const T& GetFirest() const;
	const T& GetSecond() const;
	MyPair(const T& first, const T& second);
private:
	T mFirst;
	T mSecond;
}

template<typename T>
const T& MyPair<T>::GetFirst() const
{
return mFir	st;
}

template<typename T>
const T& MyPair<T>::GetSecond() const
{
	return mSecond;
}

template<typename T>
MyPair<T>::MyPair(const T& first, const T& second)
	: mFirst(first), mSecond(second)
{
}
//Main.cpp

std::vector<MyPair<std::string> > students;

students.emplace_back(MyPair<stdd::string>("a1234", "Coco"));
students.emplace_back(MyPair<std::string>("a5678", "Mocha"));

for (std::vector<MyPair<std::string> >::iterator it = students.begin();it!- students.end(); ++it)
{
	std::cout<<it->GetFirst() <<" : "<< it->GetSecond() << std::endl;
}

템플릿 매개변수를 하나 더 만들 수 있을까?( MyPair<std::string, int> 이런 식으로)

//MyPair.h

template<typename T, typename U>
class MyPair
{
public:
	const T& GetFirest() const;
	const U& GetSecond() const;
	MyPair(const T& first, const U& second);
private:
	T mFirst;
	U mSecond;
}

template<typename T, typename U>
const T& MyPair<T>::GetFirst() const
{
	return mFirst;
}

template<typename T, typename U>
const U& MyPair<T>::GetSecond() const
{
	return mSecond;
}

template<typename T, typename U>
MyPair<T>::MyPair(const T& first, const U& second)
	: mFirst(first), mSecond(second)
{
}
//Main.cpp

std::vector<MyPair<std::string, int> > students;

students.emplace_back(MyPair<stdd::string, int>("a1234", "Coco"));
students.emplace_back(MyPair<std::string, int>("a5678", "Mocha"));

for (std::vector<MyPair<std::string, int> >::iterator it = students.begin();it!- students.end(); ++it)
{
	std::cout<<it->GetFirst() <<" : "<< it->GetSecond() << std::endl;
}

템플릿 특수화

템플릿 특수화

템플릿 특수화를 사용하는 예시

템플릿 특수화

클래스 템플릿 특수화

//정의는 생략 
template<class T> 
class MyArray 
{ 
public: 
    bool Add(T data); 
    MyArray(); 
private: 
    enum{MAX = 3}; 
    int mSize; 
    T mArray[MAX]; 
}; 
 
template<> 
class MyArray<bool> 
{ 
public: 
    bool Add(T data); 
    MyArray(); 
private: 
    enum{MAX = 3}; 
    int mSize; 
    T mArray[MAX] 
} 
 
MyArrat<bool>::MyArray() 
: mSize(0), mArray(0) 
{ 
} 
 
bool MyArray<bool>::Add(bool data) 
{ 
    if (mSize >= MAX) 
    { 
    	return false; 
    } 
    if(data) 
    { 
    	mArray |= (1 << mSize++); 
    } 
    else 
    { 
    	mArray &= ~(1 << mSize++); 
    } 
    return true; 
} 

템플릿 프로그램의 장점과 단점

템플릿 프로그램의 장점과 단점

템플릿 프로그래밍 베스트 프랙티스