c++의 템플릿은 어떤 타입이라도 타입인수로 받을 수 있는데,
이 타입을 특정 타입만으로 제한할 수도 있다.
예를들어 타원의 정보를 담는 클래스 EllipseT
를 만든다고 가정해보자
이 클래스는 내부적으로 x,y
(타원의 중점), a
(가로 축), b
(세로 축) 을 가진다.
(각도 r은 신경쓰지 않는다)
만일 이 클래스를 화면에 그리기 위한 단순 타원일 경우 정수 좌표계를 사용하는게 속도면에서 이득일 것이고,
수학적으로 정확도를 요구하는 경우 배정밀도 타입을 사용하는것이 이득이다.
이럴때 C++에서는 template 이라는 문법을 제공하는데, 이번 포스팅에서 설명하고자 할 내용은
template 클래스에서 타입을 제한하는 방법이다.
우리는 해당 좌표계로 int
,float
,double
만을 허용할 계획이다.
class EllipseT{
using Numeric = typename std::enable_if<
std::is_same<double, T>::value
|| std::is_same<float, T>::value
|| std::is_same<int, T>::value
, T>::type;
Numeric x, y, a, b;
//...Something
};
std::enable_if
는 아래와 같이 생겼고 B 가 참이면 T가 해당 타입으로 정의 된다.
template< bool B, class T = void >
struct enable_if;
레퍼런스 링크의 Possible implementation은 재미있으니 한번 보도록하자.
http://en.cppreference.com/w/cpp/types/enable_if
이 클래스의 구현은 내부적으로 typedef가 하나 되어 있다.
즉, 해당 타입을 생성해도 이 타입은 중첩 의존 타입 이름이기 때문에 템플릿 클래스에서 타입 추론이 불가하므로 앞에 typename
키워드로 명시해야 한다.
이 부분에 대해서는 이 링크 http://ikpil.com/540 를 참고.
이제 std::enable_if
의 첫번째 인자로 우리가 원하는 타입이면 참, 아닐경우 거짓을 반환하게 하면 된다.
이럴땐 std::is_same
이란 클래스를 사용할 수 있다.
http://en.cppreference.com/w/cpp/types/is_same
이 클래스도 레퍼런스의 Possible implementation 이 재미있게 구현되어 있다.
이것을 보면 바로 이해할 수 있다.
두개의 템플릿 인자를 넣고, 같은 타입이면 참 다른 타입이면 거짓을 반환한다.
이 리스트들을 or 로 나열하면 템플릿 타입 제한이 완성된다.
다른 타입으로 템플릿 클래스를 선언할경우 컴파일 에러가 발생한다.