C++ Chapter 13.6 : 함수 부분 특수화
카테고리: Cpp
태그: Cpp Programming
인프런에 있는 홍정모 교수님의 홍정모의 따라 하며 배우는 C++ 강의를 듣고 정리한 필기입니다. 😀
🌜 [홍정모의 따라 하며 배우는 C++]강의 들으러 가기!
chapter 13. 템플릿 : 클래스 템플릿 특수화
특수화
: 템플릿에서 특정 타입에 대해서 다른 실행 처리를 하고 싶을 때 그 타입에 대해서만 특수화.
🌼 부분 특수화란?
- 완전 특수화 👉 템플릿 매개 변수들을 전부 다 특수화 함
- 부분 특수화 👉 템플릿 매개 변수들이 여러개일 때 그 중 일부만 특수화 함
- 전역 함수의 경우 문제 없이 가능
- 멤버 함수의 경우 클래스 외부에선 부분 특수화 불가능
- 클래스 내부에서만 가능하므로 상속을 이용함
🔔 ‘일반 전역 함수’를 부분 특수화
특수화 하기 전
#include <iostream>
using namespace std;
template<typename T, int size>
class StaticArray
{
private:
T m_array[size];
public:
T * getArray() { return m_array; }
T& operator [] (int index)
{
return m_array[index];
}
};
template<typename T, int size>
void print(StaticArray<T, size> & array)
{
for (int count = 0; count < size; ++count)
cout << array[count] << ' '; // 🤟🤟
cout << endl;
}
int main()
{
StaticArray<int, 4> int4;
int4[0] = 1;
int4[1] = 2;
int4[2] = 3;
int4[3] = 4;
print(int4);
StaticArray<char, 14> char14;
strcpy_s(char14.getArray(), 14, "Hello, World");
print(char14);
return 0;
}
💎출력💎
1 2 3 4
H e l l o , W o r l d ?
- 클래스 템플릿 StaticArray 는 매개 변수 int size 를 가진다.
- print 함수는 멤버 함수가 아닌 전역 일반 함수다.
- 템플릿으로 구체화되는 클래스인 StaticArray 타입의 참조 & 매개변수를 받을 뿐
- // 🤟🤟 이 부분을 고쳐서
char
타입으로 특수화 되었을땐 공백 한칸씩 띄지 않도록 해보자.
특수화 하기
template<int size>
void print(StaticArray<char, size> & array)
{
for (int count = 0; count < size; ++count)
cout << array[count]; // 🤟요기가 다름🤟
cout << endl;
}
💎출력💎
1 2 3 4
Hello, World
- 특수화 해도 매개변수는 똑같이 가져가므로
template<int size>
상단에 붙여주기.T
를char
로 변경
- char 타입에만 특수화를 해서 이제 띄어쓰기 되지 않는 것을 볼 수 있다.
🔔 매개 변수가 있는 ‘멤버 함수’를 특수화
미리 내가 쓴 답변 첨부..☆
문제점
-
멤버 함수를 특수화 하기는 까다롭다.
- print() 가 일반 전역 함수일 땐 print(StaticArray<char, size> & array) 라는 매개 변수가 1개있는 함수였지만
- print() 가 StaticArray의 멤버 함수가 될 땐 그냥 매개 변수 없는 *print()* 로 표현한다.
- 이미 StaticArray의 멤버 함수이기 때문에 StaticArray 타입의 객체를 참조로 받을 필요 없이 그냥
*this
를 사용하면 된다.template<typename T, int size> class StaticArray { private: T m_array[size]; public: T * getArray() { return m_array; } T& operator [] (int index) { return m_array[index]; } void print() { for (int count = 0; count < size; ++count) cout << (*this)[count] << ' '; // ⭐ array 대신 (*this) cout << endl; } };
- 이미 StaticArray의 멤버 함수이기 때문에 StaticArray 타입의 객체를 참조로 받을 필요 없이 그냥
-
문제점 👉 특수화는 클래스 밖에서 이루어지는데 더군다나 매개 변수도 없으니
*(this)
를 어떻게 표현할지 까다로워진다.*(this)
자리에 StaticArray 타입의 객체가 있어야 하는데 매개 변수를 통해 받는 것도 없고 클래스 바깥에서 특수화 하니*(this)
를 사용할 수도 없는 문제가 발생-
해결 👉 상속 + 오버라이딩으로 해결!
해결책
자식 클래스를 특수화를 하면서 그 안에서 오버라이딩 하면
*this
사용이 가능해진다.
#include <iostream>
#include <stdio.h>
using namespace std;
template<typename T, int size>
class StaticArray_BASE
{
private:
T m_array[size];
public:
T * getArray() { return m_array; }
T& operator [] (int index)
{
return m_array[index];
}
void print()
{
for (int count = 0; count < size; ++count)
cout << (*this)[count] << ' ';
cout << endl;
}
};
template<typename T, int size>
class StaticArray : public StaticArray_BASE<T, size>
{
};
template<int size>
class StaticArray<char, size> : public StaticArray_BASE<char, size>
{
public:
void print()
{
for (int count = 0; count < size; ++count)
cout << (*this)[count];
cout << endl;
}
};
int main()
{
StaticArray<int, 4> int4;
int4[0] = 1;
int4[1] = 2;
int4[2] = 3;
int4[3] = 4;
int4.print();
StaticArray<char, 14> char14;
strcpy_s(char14.getArray(), 14, "Hello, World");
char14.print();
return 0;
}
- 기존 StaticArray 클래스 이름을
StaticArray_Base
로 바꿔주자. 기존 클래스를 부모 클래스로 할 것.template<typename T, int size> class StaticArray_BASE { private: T m_array[size]; public: T * getArray() { return m_array; } T& operator [] (int index) { return m_array[index]; } void print() { for (int count = 0; count < size; ++count) cout << (*this)[count] << ' '; // ⭐ array 대신 (*this) cout << endl; } };
StaticArray_Base
를 상속하는StaticArray
자식 클래스를 만든다. 빈 클래스로 만들어 온전히 자기 것 없이 전부 다 상속 받도록 한다.template <typename T, int size> class StaticArray : public StaticArray_Base<T, size> { };
- 빈 자식 클래스인
StaticArray
자식클래스를 특수화 하고 그 안에서 오버라이딩 해준다. ⭐이제 *this 사용이 가능해진다. 상속으로StaticArray_BASE
의 정보를 받았기 때문에.template<int size> class StaticArray<char, size> : public StaticArray_BASE<char, size> { public: void print() { for (int count = 0; count < size; ++count) cout << (*this)[count]; cout << endl; } };
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기