leesangwon0114

I am Research Engineer. Currently working in KT.

C++Template 17. traits summary

16 Aug 2018 » c++

codenuri 강석민 강사 강의 내용기반으로 정리한 내용입니다.

C++ 표준 type_traits #1

  1. include
  2. 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);
}