C++프로그래밍 (Template)

2022. 6. 7. 12:28C++

함수

기본 인자 전달

 

일반화 프로그래밍


타입에 관계없이 알고리즘을 기술하는 프로그래밍 패러다임

void swap(int a,int b)

void swap(float a,float b)

void swap(char a,char b)

3개는 타입은 다르지만 기술하는것은 똑같다. 

 

템플릿 문법

클래스 템플릿함수 템플릿으로 구분된다

.

템플릿은 하나 이상의 템플릿 피라미터와 함께 매개변수화 된다.

템플릿 피라미터에는 비 타입 피라미터,타입 피라미터,템플릿 피라미터가 있다. 타입도 인자처럼 전달할수 있다. 

// 타입 파라미터는 타입을 받을 수 있다.
template <typename T> class A { };
template <class T> class B { }; // typename 대신 class를 사용할 수 있다.
template <typename T = int> class C { }; // 기본 인자 전달도 가능하다.
// C<> c; c는 C<int> 타입이다.
 
// 비 타입 파라미터는 구체적인 타입을 지정하는 것이다.
// 비 타입 파라미터에 넣을 수 있는 타입으로는
// 정수형, 포인터, 레퍼런스 등이 있다.
// 마찬가지로 기본 인자 전달이 가능하다.
template <size_t N = 10> struct Array { int Container[N]; };
 
// 템플릿 파라미터는 템플릿을 전달하는 것이다.
template <typename T> class Container { };
template <template<typename> typename Container = Container<int>> class Temp { };

특수화

 

특수화는 컴파일 타임에 일어나면, 컴파일러가 템플릿을 기반으로 특정 타입을 생성한다.

 

template <typename T, size_t N>
struct IdiotArray { T Container[N]; };
 
IdiotArray<int, 10> arr;
// 컴파일러는 컴파일 타임에 아래와 같은 코드를 생성한다.
// template <>
// struct IdiotArray { int Container[10]; };

따라서 일반적으로 템플릿은 헤더 파일에 모든 내용을 적으며, 정의를 소스 파일에 나눠서 적으면 링크 오류가 발생한다.

 

// Temp.h
template <typename T>
class A
{
public:
    void SetData(const T& data);
    T GetData() const;
private:
    T _data;
};
 
// Temp.cpp
// 이 파일 아래에 있는 템플릿은 인스턴스가 만들어지지 않는다.
template <typename T>
void A<T>::SetData(const T& data)
{
    _data = data;
}
 
template <typename T>
T A<T>::GetData() const
{
    return _data;
}
 
// Main.cpp
int main()
{
    A<int> a;
    // 아래와 같이 인스턴스가 만들어진다.
    // 정의가 없음을 볼 수 있다.
    // template <>
    // class A
    // {
    // public:
    //     void SetData(const int& data);
    //     int GetData() const;
    // private:
    //     int _data;
    // };
 
    a.SetData(10); // 링크 오류! 정의가 없음.
}

 

사용자가 특정 템플릿 인자에 대해 코드를 커스터마이징 할 수도 있는데, 모든 템플릿 파라미터에 대해 특수화를 하는 걸 명시적 특수화(Explicit Specialization), 일부만 하는 걸 부분 특수화(Partial Specialization)라고 한다.

 

#include <iostream>

template <typename T1, typename T2>
void Print(const T1& a, const T2& b)
{
    std::cout << a << '\n';
    std::cout << b << '\n';
}

// 명시적 특수화
template <>
void Print(const int& a, const double& b)
{
    std::cout << "이것은 명시적으로 특수화 되었습니다.\n";
}

// 부분 특수화
template <typename T>
void Print(const T& a, const int& b)
{
    std::cout << "이것은 부분적으로 특수화 되었습니다.\n";
}

void main()
{
double d = 1.0;
Print(d, d); // Print<double, double>; 암시적 특수화 버전 호출

int i = 1;
Print(i, d); // Print<int, double>; 명시적 특수화 버전 호출

Print(d, i); // Print<double, int>; 부분 특수화 버전 호출

}

이거 쓰는 이유를 알아냄

 

STL에 있는 library쓸때 쓰는 string ,vector , stack ,ForwardList , List 들을 템플릿으로 구 현해서 쓰기좋게 만들어 놓은거였음  

'C++' 카테고리의 다른 글

C++프로그래밍  (0) 2022.06.07
C++ 객체지향  (0) 2022.06.02
C++ 객체지향 프로그래밍 상속쪽 오류  (0) 2022.05.31
객체지향 프로그래밍  (0) 2022.05.30
202204_15 c++ 구조체  (0) 2022.04.15