[모던C++입문] 3.6 템플릿 특수화
- 📕 Book/모던C++입문
- 2021. 7. 12.
템플릿 특수화
- 템플릿은 많은 인수타입에 대해 동일한 구현을 사용할수 있다.
- 그러나 일부 타입에 대해서는 다른동작을 구현해야 할때도 있다.
- 이를 위해 템플릿 특수화(Template Speicalization)을 사용하자.
하나의 타입에 대한 특수화
- 벡터 클래스에서 bool타입에 대해 특수화
- bool값을 1바이트로 패킹하여 메모리 절약을 해보자.
template <>
class vector<bool>
{
public:
explicit vector(int size)
: my_size(size), data(new unsigned char[(my_size+7) / 8])
{}
vector() : my_size(0) {}
//상수 접근 연산자
bool operator[](int i) const { return (data[i/8] >> i%8) & 1; }
vector_bool_proxy operator[](int i)
{ return {data[i/8], i%8}; } //중괄호 리스트로 생성자 호출
private:
int my_size;
std::unique_ptr<unsigned char[]> data;
};
class vector_bool_proxy
{
public:
vector_bool_proxy(unsigned char& byte, int p) : byte(byte), mask(1 << p) {}
operator bool() const { return byte & mask; }
//대입 연산자
vector_bool_proxy& operator=(bool b)
{
if (b)
byte|= mask;
else
byte&= ~mask;
return *this;
}
private:
unsigned char& byte;
unsigned char mask;
};
함수 특수화 및 오버로딩
함수를 특정타입으로 특수화 하기
- 함수 템플릿 특수화는 사용하지 말자.
모호함
template<typename Base, typename Exponent>
Base inline power(const Base& x, const Exponent& y);
template<typename Base>
Base inline power(const Base& x, int y);
template<typename Exponent>
double inline power(double x, const Exponent& y);
power(3.0, 2); //세 오버로드가 모두 일치한다.
//모호함을 없애기 위해선 다음 오버로드가 필요하다
double inline power(double x, int y);
부분 특수화
//앞서 사용했던 템플릿 클래스인 vector와 complex 를 이용하여 다음과 같은 예제
//> >사이에 공백을 두어야한다 붙이면 시프트 연산자로 해석
template<typename Real>
class vector<complex<Real> >
{...}
//여러 매개 변수가 있는 클래스에도 사용 가능하다
template<typename Value, typename Param>
class vector<sparse_matrix<Value, Param> >
{...}
//포인터 또한 특수화가 가능
template<typename T>
class vector<T*>
{...}
부분 특수화한 함수
- 함수 템플릿은 부분 특수화 할수 없지만 오버로드를 사용하여 비슷하게 사용가능
template<typename T>
inline T abs(const T& x)
{
return x < T(0) ? -x : x;
}
template<typename T>
inline T abs<const std::complex<T>& x)
{
return sqrt(real(x) * real(x) + imag(x) * imag(x));
}
반응형