using 의 쓰임새

C++/C++ 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 ;

 

 
Posted by Elan
: