enable_if와 is_integral

hyenam·2022년 4월 22일
0

ft_containers

목록 보기
5/8

사실 이터레이터만 구현하면서 왜 enable_if와 is_integral를 구현하라는건지 잘 이해가 안갔다. 만들어도 쓸곳이 없어보였다. 하지만 벡터 생성자 구현을 하면서 왜 사용하게 되는지 이해가 갔다...

벡터 3번째 생성자인 범위 생성자 때문이었다.
3번째 생성자에 enable_if없이 그냥 cplusplus페이지 프로토타입을 그대로 사용하게 되면
인자가 두개가 들어왔을때 fill 생성자하고 범위 생성자 두개 중 뭐에 들어가야 하는지 모르게 되는 것이다.
그래서 범위 생성자에 enable_if를 사용해서 이터레이터 일때만 해당 범위 생성자가 작동하게 해주면 되는 것이다.

enable_if

enable_if를 사용하면 들어온 인자와 조건을 확인해서 flase가 리턴이 되면 해당 함수를 오버로딩 후보군에서 제외하게 해주는 함수이다.

template<bool Cond, class T = void> struct enable_if {};
template<class T> struct enable_if<true, T> { typedef T type; };

enable_if는 이런 모양으로 생겼다. 만약 type T가 enable_if::type이 가능할 경우 Cond는 true가 된다.

그렇지 않으면 enable_if::type이 정의되지 않고 이를 사용하여 컴파일을 시도하면 실패한다.

is_integral

vector처럼 is_integral도 템플릿 특수화로 구현이 되어있다.
왜냐하면 체크하는 타입의 종류가 엄청나게 많기 때문이다. 종류가 15개 정도 되는데 자세한건 이 페이지를 보는 것이 좋다.

is_integral는 자료형별로 특수화가 되어있고, false_type과 true_type을 상속 받는 빈 구조체로 되어있다.

그리고 해당 두 타입의 생김새를 보면

typedef integral_constant<bool,true> true_type;
typedef integral_constant<bool,false> false_type;

integral_constant라는 구조체의 객체의 별칭임을 알 수 있다.

integral_constant는 정수 계열 형식을 타입으로 만들 수 있게 하는 템플릿이다.

template <class T, T v>
struct integral_constant {
  static constexpr T value = v;
  typedef T value_type;
  typedef integral_constant<T,v> type;
  constexpr operator T() { return v; }
};

constexpr 키워드는 해당 키워드가 붙은 객체 또는 함수의 리턴값을 컴파일 타임에 알수있게 해주는 C++11키워드이다.

간략하게 정리를 하면
is_integral는 integral_constant는의 객체인 false_type혹은 true_type을 상속받는 빈 구조체이다.

이제 enable_if와 is_integral를 range 생성자 인자에 추가를 하고

ft::vector<int> a(3, 100);

해당 코드를 컴파일 해보면 더이상 range 생성자 오버로딩에 걸려 오류가 뜨지않고 잘 컴파일이 되는 것을 볼 수 있다.


profile
공부한 걸 정리하고 있습니다.

0개의 댓글

관련 채용 정보