타입 관련 연산을 위한 템플릿 메타 함수 들을 제공해주는 type_traits 라이브러리에대해 al ah bo jha.
템플릿 메타 함수
:함수는 아니지만 마치 함수 처럼 동작하는 탬플릿 클래스들
*보통의 함수들은 값 에 대해 연산을 수행, 하지만 메타 함수는 타입 에 대해 연산을 수행
type_traits의 여러가지 메타 함수 중 하나인
is_void의 코드
#include <iostream>
template <typename T>
struct is_void {
static constexpr bool value = false;
};
template <>
struct is_void<void> {
static constexpr bool value = true;
};
template <typename T>
void tell_type() {
if (is_void<T>::value) {
std::cout << "T 는 void ! \n";
} else {
std::cout << "T 는 void 가 아니다. \n";
}
}
int main() {
tell_type<int>(); // void 아님!
tell_type<void>(); // void!
}
템플릿 특수화를 통해서 void 타입의 경우에만 value에 true 값을 대입하는 방식
void를 제외한 타입은 false
(
*constexpr
:C++ 11 에서 새롭게 도입된 constexpr 키워드에 대해 알아보도록 하겠습니다. constexpr 키워드는 객체나 함수 앞에 붙일 수 있는 키워드로, 해당 객체나 함수의 리턴값을 컴파일 타임에 값을 알 수 있다 라는 의미를 전달
어떠한 식이 상수식 이라고 명시해주는 키워드
*(상수식 (Constant expression)
:컴파일러가 컴파일 타임에 어떠한 식의 값을 결정할 수 있는 식
출처: https://modoocode.com/293
)
*static_assert(since c++ 11)
: 식이 참인지 아닌지 컴파일 타임에 확인
static_assert를 이용하면 컴파일 단계에서 오류를 발생시킬 수 있다.
SFINAE(Substitution failure is not an error 치환 오류는 컴파일 오류가 아니다)
:템플릿은 컴파일러가 타입을 유추한 다음 해당 타입으로 치환하여 동작합니다. 컴파일러가 타입을 유추하면서 올바르지 않은 식에 대해서는 오류가 아닌 후보군 제외만 시킴(올바른 식이 하나도 없다면(유추를 했는데 치환할 적당한 타입이 없다면) 에러)
*SFINAE를 활용하여 원하지 않는 타입들에 대해 오버로디 후보군에서 제외가 가능
enable_if
: SFINAE를 통해 조건에 맞지 않는 함수들을 오버로딩 후보군에서 쉽게 뺄 수있게 도와주는 템플릿 메타 함수 (첫번째 인자가 bool 타입으로서 보통 type_traits의 value 를 이용하는 방식으로 많이 쓴다.(그래서 도와준다고 표현))
template<bool B, class T = void>
struct enable_if {};
template<class T>
struct enable_if<true, T> { typedef T type; };
확인하고자하는 조건을 B에 전달, 참이면 enable_if::type 의 타입이 T, 거짓이면 type이 존재하지 않게됨
template <typename T,
typename = typename std::enable_if<std::is_integral<T>::value>::type>
이런식으로 템플릿을 사용하여 원하는 타입(예제는 정수 타입)에대한 특수화? 오버로딩?을 작성할 수 있다.
*다른 타입을 특수화 하지않고 컴파일시 컴파일에러를 확인할 수 있다.