codenuri 강석민 강사 강의 내용기반으로 정리한 내용입니다.
C++ 표준 type_traits #1
-  
include  - is_pointer, is_array, extent(배열의 크기), remove_pointer, result_of / invoke_result
 
#include <iostream>
#include <type_traits>
using namespace std;
template<typename T> void foo(T a)
{
	typename remove_pointer<T>::type t;
	bool b = is_pointer<T>::value;
}
int main()
{
	int n = 10;
	foo(&n);
}
C++ 표준 type_traits 사용법
1.변형된 타입을 얻는 traits
- typename remove_pointer
::type n;  - remove_pointer_t
n; -> C++14 부터 지원  
#include <iostream>
#include <type_traits>
using namespace std;
/*
// C++14 부터 지원됨
template<typename T>
using remove_pointer_t = typename remove_pointer<T>::type;
*/
template<typename T> void foo(T a)
{
	// 포인터를 제거한 타입을 구하고 싶다.
	// typename remove_pointer<T>::type t;
	remove_pointer_t<T> n;
	cout << typeid(n).name() << endl; // int
	bool b = is_pointer<T>::value;
}
int main()
{
	int n = 10;
	foo(&n);
}
2.타입의 정보를 조사하는 traits
- bool b = is_pointer
::value  - bool b = is_pointer_v
; -> C++17 부터 지원  - 함수 오버로딩 사용(true_type, false_type)
 
#include <iostream>
#include <type_traits>
using namespace std;
/*
// C++ 17부터 지원
// variable template
template<typename T>
inline constexpr bool is_pointer_v = is_pointer<T>::value;
*/
void foo_imp(true_type) {}
void foo_imp(false_type) {}
template<typename T> void foo(T a)
{
	// T가 포인터 인지 알고 싶다.
	// bool b = is_pointer<T>::value;
	bool b = is_pointer_v<T>;
	//if (is_pointer_v<T>)
	// C++ 17
	if constexpr (is_pointer_v<T>)
	{
		cout << *a << endl;
	}
	foo_imp(is_pointer<T>());
}
int main()
{
	int n = 10;
	foo(&n);
}
C++ 표준 type_traits #2
is_array::value, extent<T,0>::value 
#include <iostream>
#include <type_traits>
using namespace std;
// array => pointer : decay
// template<typename T> void foo(T a)
template<typename T> void foo(T& a)
{
	if(is_array<T>::value)
	{
		cout << "array" << endl;
		cout << extent<T, 0>::value << endl; //3
		cout << extent<T, 1>::value << endl; //2
	}
}
int main()
{
	int x[3][2] = {1,2,3,4,5,6};
	foo(x);
}
is_same<T, U>::value
#include <iostream>
#include <type_traits>
using namespace std;
template<typename T, typename U> void foo(T a, U b)
{
	bool ret = is_same<T, U>::value;
	cout << ret << endl;
}
int main()
{
	foo(0,0);
}
remove_cv<T,U>::type
const 와 volatile 제거한 type을 꺼내서 비교해 보기
#include <iostream>
#include <type_traits>
using namespace std;
template<typename T, typename U> void foo(T a, U b)
{
	bool ret = is_same<typename remove_cv<T>::type, typename remove_cv<U>::type>::value;
	cout << ret << endl;
}
int main()
{
	foo<int, const int>(0,0);
}
decay<T,U>::type
#include <iostream>
#include <type_traits>
using namespace std;
// array => pointer : decay 이용
template<typename T, typename U> void foo(T a, U b)
{
	bool ret = is_same<decay<T>::type, decay<U>::type>::value;
	cout << ret << endl;
}
int main()
{
	foo<int[3], int*>(0,0);
}
is_base_of<T,U>::type
상속관계
#include <iostream>
#include <type_traits>
using namespace std;
template<typename T, typename U> void foo(T a, U b)
{
	boot ret = is_base_of<T, U>::value;
	// www.cppreference.com 의 type supports
	cout << ret << endl;
}
int main()
{
	foo<int[3], int*>(0,0);
}