photoner 2020. 10. 13. 12:31
728x90
반응형

템플릿

  • 함수 템플릿

모형자에 비유하여 함수 템플릿을 설명

모형자는 모형을 만들어 낸다. 모형의 틀은 결정되어 있지만, 모형의 색은 결정되어 있지 않아서 결정해야함.
함수 템플릿은 함수를 만들어 낸다. 함수의 기능은 결정되어 있지만, 자료형은 결정되어 있지 않아서 결정해야함.

, 함수 템플릿은 함수를 만드는 도구가 될 수 있다. 함수의 기능은 정해져 있으나 그 기능 수행에 사용되어지는 요소들의 자료형이 결정되어 있지 않기 때문에 다양한 자료형의 함수를 만들어 낼 수 있다.

위의 예는 기본 함수를 나타낸 것이다. 정수형에 대한 곱셈 연산을 진행하는 함수이다. 이를 템플릿으로 정의하게 되면 다음과 같다.

곱셈 연산을 진행하는 함수이지만 연산의 대상에 대한 자료형은 결정되어 있지 않고, 나중에 T를 대신해서 실제 자료형을 결정하겠다는 뜻이다. 여기서 T는 자료형을 결정짓지 않겠다는 의미이고, 함수를 만들어 내는 템플릿을 정의하기 위해 사용된 것이다. 위의 예를 완성시키면 다음과 같다.

14번 라인, 15번 라인에서 <자료형> 방식을 통해 함수 템플릿의 T 를 결정 짓고 호출한다는 뜻이다. 컴파일러는 컴파일 할 때, 각 자료형에 따른 함수를 하나씩 만들고, 호출하게 된다. 컴파일 속도는 떨어지지만 실행 속도가 지연되지는 않으므로 문제가 없다.

다음과 같이 함수를 호출할 때, <자료형> 형식으로 호출하지 않고, 일반 함수 호출 방법도 허용한다. 다만, 컴파일러에 의해서 전달되는 인자로 호출될 자료형의 함수를 판단한다.

17, 18번 라인과 같이 호출 가능.

 

  • 함수 템플릿과 템플릿 함수

 

  • 두 개의 이상의 자료형을 이용하기

8번 라인에서 매개 변수의 타입은 이미 정해졌기 때문에 호출 시 18~ 20번 라인과 같이 템플릿 T1, T2의 자료형을 명시해줘야 한다. 그리고 12번 라인에서 형 변환의 두 가지 방법이 나오는데 모두 같은 효과를 지닌다.

  • 함수 템플릿의 특수화

함수 템플릿의 특수화란 함수 템플릿을 통해 템플릿 함수를 구현할 때, 구성 방법에 예외를 둘 필요가 있을 때 사용하는 방법이다. 위의 예제에서 6번 라인에서의 compare 함수는 두 인자에 대한 비교 후 큰 값을 출력하도록 되어 있는데 18번 라인과 같은 경우는 의미가 없는 비교가 된다. 왜냐하면 사전식 비교나 문자열 길이 비교가 아닌 주소 값의 비교이기 때문이다. 이러한 경우, compare 템플릿 함수의 구성에서 문자열에 대한 템플릿 함수는 의미가 없는 구성이기 때문에 다음과 같이 예외로 두고 새롭게 정의해야 한다.

12, 18번 라인과 같이 적용하면 함수 템플릿의 특수화가 적용이 된다. , 예외가 적용되는 것이다. 12, 18번 라인들의 경우 각각 char*, const char* 형의 템플릿 함수는 예외로 두고 직접 제시할 테니 해당 함수들이 호출될 경우 템플릿 함수로 구성하지 말고 가져다 쓰라는 뜻이다. 위의 예에서는 문자열에 대한 비교에서 길이 비교, 사전식 비교를 진행하는 예외 두 가지를 두었다

  • 클래스 템플릿

클래스 또한 클래스 템플릿을 정의하고 이를 기반으로 컴파일러에 의해 템플릿 클래스를 만들 수 있다.

위의 예에서 볼 수 있듯이 클래스 템플릿을 정의하고 이를 통해 템플릿 클래스의 객체를 생성할 수 있는데 25~27번 라인처럼 T에 대한 자료형을 명시한 채로 객체를 생성해야 한다. 함수처럼 생략은 불가능하다.

클래스 내의 템플릿 함수의 정의와 선언을 분리하는 방법이다.

  • 특정 템플릿 클래스의 객체를 인자로 받는 일반 함수 정의 및 friend 선언

위와 같이 일반 함수를 대상, 매개 변수로 템플릿 클래스를 받을 수 있으며 템플릿 클래스를 상대로 friend 선언 또한 가능하다.

  • 클래스 템플릿 특수화

함수 템플릿의 특수화를 하는 이유 : 특정 자료형에 대해서 구분이 되는 다른 기능을 보이기 위함.
클래스 템플릿의 특수화를 하는 이유 : 특정 자료형을 기반으로 생성된 객체에 대해서 구분이 되는 다른 행동 양식을 적용하기 위함.

19, 20번 라인과 같이 특수화시킬 수 있다.

  • 클래스 템플릿의 부분 특수화와 우선 순위

34번 라인과 같은 경우를 부분 특수화라고 한다. 부분적으로만 자료형을 지정하지 않았기 때문이다. 그렇다면 전체 특수화와 부분 특수화 모두 지정한 경우 50번 라인과 같이 겹치는 자료형에 의한 객체 생성이 발생한다면 어떻게 될까? 그 결과는 전체 특수화된 클래스를 대상으로 객체가 생성된다. , 전체 특수화가 부분 특수화보다 우선시 된다.

  • 템플릿 매개 변수와 템플릿 인자

템플릿 정의할 시에 결정되지 않은 자료형을 의미하는 T, T1 따위의 문자를 템플릿 매개 변수라고 함. 이러한 템플릿 매개 변수에 전달되는 자료형 정보를 템플릿 인자라고 한다.

이러한 템플릿 매개 변수에는 변수의 선언이 올 수 있다.

6번 라인과 같이 템플릿 매개 변수에 일반 변수의 선언이 허용되고, 템플릿 인자로 값을 받을 수 있다. 이 때 받아온 템플릿 인자를 통해서 10번 라인과 같이 멤버 변수에 대한 배열 길이를 정의 한다. 배열 길이의 정의는 생성자로도 충분히 할 수 있지만 생성자를 통해서 동적 할당을 통한 배열 구현의 경우 24번 라인에 대해서 컴파일 에러가 발생하지 않지만, 템플릿 인자를 통한 배열 구현의 경우 24번 라인에 대해서 컴파일 에러가 발생한다. 왜냐하면 <int, 5><int, 3>은 서로 다른 자료형으로 취급하기 때문이다.

  • 템플릿 매개변수의 디폴트 값

템플릿 매개변수 또한 디폴트 값을 가질 수 있다.

  • 템플릿과 static

Static 멤버는 클래스 변수로 객체 별로 생성되는 변수가 아닌 클래스 별로 생성되는 변수로서 객체가 생성되지 않은 상황에서도 이미 생성되어 있는 변수이다. 템플릿을 적용한 템플릿 클래스에서 또한 템플릿 클래스 별로 static 멤버 변수를 유지한다. , 위의 예에서 Data<int> 클래스에 하나, Data<short> 클래스에 하나씩 유지한다. 그렇기 때문에 d1d2(or d3d4)는 서로 다른 객체이지만 static 멤버가 공유된 결과를 볼 수 있다.

 

  • template<typename T …> / template <>

template<typename T …> / template <>

위 키워드의 쓰임은 함수 템플릿 및 클래스 템플릿을 정의 혹은 그 외의 템플릿 관련 정의에 대해서 위와 같은 선을 두고 템플릿의 일부 또는 전부를 정의하고 있다는 사실을 컴파일러에게 알린다. , T가 무엇인지 그리고 정의 및 특수화, 부분화 정의를 시키고 있다 라는 것을 알리기 위함이다. 전자의 경우는 템플릿 매개변수가 사용된 정의에 대해서 관련 템플릿 문자를 맞춰서 선언하고, 후자는 템플릿 문자를 사용하지 않았을 때 선언한다.

  • 템플릿 static 멤버 변수 초기화의 특수화

위 예시의 한 부분인데 위와 같이 static 멤버를 초기화하면 모든 템플릿 클래스에 대해서 0으로 초기화 된다.( Data<char>, Data<int>, Data<long>, Data<short> ) 하나의 자료형에 대해서만 다른 값으로 초기화해야 하는 경우는 다음예의 22, 23번 라인과 같이 특수화 하면 된다.

728x90
반응형