is_integral?

😎·2023년 3월 3일
0

CPP

목록 보기
46/46

is_integral

이전에 enable_if 에 대해 설명을 하면서 is_integral 에 대해 잠시 언급했다.

https://velog.io/@jaekim/SFINE-%EC%99%80-enableif

간략히 정리하면... 템플릿의 제네릭 변수(T)에 어떤 자료형이 들어왔을 때, 컴파일러가 치환 할지 말지 결정하는 순간이 온다.
이때 is_integral 의 value 멤버가 true 인지 false 인지에 따라 결정했었다. (정확히는 is_integral 의 부모 클래스인 true_type(또는 false_type)의 value 멤버이다.)

아래 코드는 ! 가 있기 때문에, true 가 반환되면 false 로 인식해서 치환하지 않는다.

template <typename T, typename std::enable_if<!std::is_integral<T>::value, T>::type* = nullptr>
T::value_type negative(const int& t) {
  /* ... */
}

예시

그렇다면 is_integral 은 어떻게 구현되어 있을까? 템플릿 함수가 false_typetrue_type 클래스를 상속받는데, 특정 자료형으로 특수화가 됐고 각 자료형에 따라 상속 받는 bool 값이 다르다.

template <typename T>
struct is_integral : public false_type<false, void> {};

template <>
struct is_integral<bool> : public true_type<true, bool> {};

template <>
struct is_integral<char> : public true_type<true, char> {};

template <>
struct is_integral<long long> : public true_type<true, long long> {};

template <>
struct is_integral<unsigned long long>
    : public true_type<true, unsigned long long> {};

true_typefalse_type 은 다음처럼 되어있다.

template <bool is_integral, typename T>
struct true_type {
  const static bool value = true;
  typedef T         type;
};

template <bool is_integral, typename T>
struct false_type {
  const static bool value = false;
  typedef T         type;
};

각 클래스(true_type, false_type) 에는 value 멤버 변수를 갖고 있고 true_type::value 에는 true, false_type::value 에는 false 값이 있다.

** 이 값은 특수화된 is_integral 함수에 들어오는 자료형에 따라 value 의 값이 달라진다.

예를 들어 위 코드를 바탕으로 다음과 같이 main 문을 만들어서 실행하자.

다음 결과가 나온다.
float 으로 특수화된 is_integral 은 없다. 그래서 디폴트 함수로 넘어가게 되며, 디폴트 함수는 false_type 클래스를 상속받았기 때문에 false, 즉 0을 반환한다.
그 외에 나머지는 true_type 클래스를 상속받아서 true, 즉 1 을 반환한다.

profile
jaekim

0개의 댓글