C++/C++
using 의 쓰임새
Elan
2021. 12. 25. 19:34
using 키워드
1. 네임 스페이스를 생략하는 방법
#include <vector>
using namespace std; //네임 스페이스 생략하는 방법
vector<int> v;
2. Type alias
using DWORD = int ;
using FP = void(*)(int);
좀 특별한 type alias를 소개한다.
template <bool B, class T=void>
struct myType{};
template<class T>
struct myType<true, T> { typedef T type; // type alias };
template<bool B, class T=void>
using myType_t = typename myType<B, T>::type;
myType은 템플릿 특수화에 의해 오버로딩된 2개의 템플릿 구조체이다.
그리고 myType_t가 바로 템플릿 특수화에 의해 만들어진 녀석이다.
typename 이라는 키워드 때문에 type myType<B, T>::type 은 타입으로 평가되고,
myType_t 는 단순히 타입만을 의미하게된다.
이걸 이용하면 아래와 같은 코드도 가능해진다.
struct T {
enum { int_t, float_t } type;
template <typename Integer,
std::enable_if_t<std::is_integral<Integer>::value, bool> = true
>
T(Integer) : type(int_t) {}
template <typename Floating,
std::enable_if_t<std::is_floating_point<Floating>::value, bool> = true
>
T(Floating) : type(float_t) {} // OK
};
잘 보면 다음과 같은 표현이 보일 것이다.
template <typename Integer,
std::enable_if_t<std::is_integral<Integer>::value, bool> = true >
T(Integer) : type(int_t) {}
여기서 std::enable_if_t<std::is_integral<Integer>::value, bool> = true 라는 표현은 다소 생소할 것이다.
이것은 템플릿 문법 중 이름 없는 인자에 해당한다.
아래 코드를 보면 true값이 인자로 바로 들어간 것을 볼 수 있다.
즉, 아래의 템플릿 인자로 들어간 true와 위 코드의 std::enable_if_t<std::is_integral<Integer>::value, bool> = true는
같은 방식으로 boolean 값이 전달된 것이라고 보면된다.
template<typename Integer, true>
T(Integer) : type(int_t) {}
이를 SFINAE에서 많이 애용하므로 잘 알아두자.
3. template alias
// 3. template alias
template<typename T>
class Point { T x, y; };
template<typename T>
using PT = Point<T>;
4. template arguments alias
// 4. 템플릿 인자 고정
template<typename T, typename U>
using Duo = pair<T, U>;
template<typename T>
using I_Duo = pair<int, T>; //pair의 첫번째 인자를 int형으로 고정
5. 복잡한 문법 단순화
// 5. 복잡한 문법 단순화
template< class T > struct remove_pointer {typedef T type;};
template< class T > struct remove_pointer<T*> {typedef T type;};
template< class T > struct remove_pointer<T* const> {typedef T type;};
template< class T > struct remove_pointer<T* volatile> {typedef T type;};
template< class T > struct remove_pointer<T* const volatile> {typedef T type;};
template<typename T>
using remove_pointer_t = typename remove_pointer<T>::type ;