Type alias, alias template (since C++11)
타입 별칭은 이전에 정의된 타입을 참조하는 이름입니다(
typedef
와 유사함).
별칭 템플릿은 타입들의 패밀리를 참조하는 이름입니다.
목차 |
구문
별칭 선언은 선언 으로 다음과 같은 구문을 가집니다:
using
identifier
attr
(선택 사항)
=
type-id
;
|
(1) | ||||||||
template
<
template-parameter-list
>
|
(2) | ||||||||
template
<
template-parameter-list
>
requires
constraint
|
(3) | (C++20 이후) | |||||||
| attr | - | 임의 개수의 속성 을 선택적으로 지정하는 시퀀스 |
| identifier | - | 이 선언으로 도입되는 이름으로, 타입 이름 (1) 또는 템플릿 이름 (2) 이 됨 |
| template-parameter-list | - | 템플릿 매개변수 목록 , 템플릿 선언 과 동일 |
| constraint | - | 이 별칭 템플릿이 수용하는 템플릿 매개변수를 제한하는 제약 조건 표현식 |
| type-id | - | 추상 선언자 또는 다른 유효한 타입 식별자 ( 타입 식별자 에서 언급된 대로 새로운 타입을 도입할 수 있음). 타입 식별자 는 직접 또는 간접적으로 identifier 를 참조할 수 없음. 식별자의 선언 지점 이 type-id 뒤의 세미콜론임에 유의 |
설명
template<class T> struct Alloc {}; template<class T> using Vec = vector<T, Alloc<T>>; // type-id is vector<T, Alloc<T>> Vec<int> v; // Vec<int> is the same as vector<int, Alloc<int>>
별칭 템플릿을 특수화한 결과가 종속적인 template-id 인 경우, 이후의 치환들은 해당 template-id에 적용됩니다:
template<typename...> using void_t = void; template<typename T> void_t<typename T::foo> f(); f<int>(); // error, int does not have a nested type foo
별칭 템플릿을 특수화하여 생성된 타입은 직접적 또는 간접적으로 자신의 타입을 사용하는 것이 허용되지 않습니다:
template<class T> struct A; template<class T> using B = typename A<T>::U; // type-id is A<T>::U template<class T> struct A { typedef B<T> U; }; B<short> b; // error: B<short> uses its own type via A<short>::U
별칭 템플릿은 템플릿 템플릿 매개변수를 추론할 때 템플릿 인자 추론 에 의해 절대 추론되지 않습니다.
별칭 템플릿을 부분적으로 또는 명시적으로 특수화 하는 것은 불가능합니다.모든 템플릿 선언과 마찬가지로, alias template은 클래스 범위 또는 네임스페이스 범위에서만 선언될 수 있습니다.
|
람다 표현식 이 앨리어스 템플릿 선언에 나타날 때, 해당 람다 표현식이 의존적이지 않은 경우에도 템플릿의 인스턴스화마다 그 타입이 다릅니다. template<class T> using A = decltype([] {}); // A<int> and A<char> refer to different closure types |
(since C++20) |
참고 사항
| 기능 테스트 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
__cpp_alias_templates
|
200704L
|
(C++11) | Alias templates |
키워드
예제
#include <iostream> #include <string> #include <type_traits> #include <typeinfo> // 타입 별칭, 다음과 동일함 // typedef std::ios_base::fmtflags flags; using flags = std::ios_base::fmtflags; // 'flags' 이름이 이제 타입을 나타냄: flags fl = std::ios_base::dec; // 타입 별칭, 다음과 동일함 // typedef void (*func)(int, int); using func = void (*) (int, int); // 'func' 이름이 이제 함수 포인터를 나타냄: void example(int, int) {} func f = example; // 별칭 템플릿 template<class T> using ptr = T*; // 'ptr<T>' 이름이 이제 T에 대한 포인터 별칭임 ptr<int> x; // 템플릿 매개변수를 숨기기 위해 사용된 타입 별칭 template<class CharT> using mystring = std::basic_string<CharT, std::char_traits<CharT>>; mystring<char> str; // 타입 별칭은 멤버 typedef 이름을 도입할 수 있음 template<typename T> struct Container { using value_type = T; }; // 제네릭 프로그래밍에서 사용 가능 template<typename ContainerT> void info(const ContainerT& c) { typename ContainerT::value_type T; std::cout << "ContainerT is `" << typeid(decltype(c)).name() << "`\n" "value_type is `" << typeid(T).name() << "`\n"; } // std::enable_if 구문을 단순화하기 위해 사용된 타입 별칭 template<typename T> using Invoke = typename T::type; template<typename Condition> using EnableIf = Invoke<std::enable_if<Condition::value>>; template<typename T, typename = EnableIf<std::is_polymorphic<T>>> int fpoly_only(T) { return 1; } struct S { virtual ~S() {} }; int main() { Container<int> c; info(c); // 이 함수에서 Container::value_type은 int가 됨 // fpoly_only(c); // 오류: enable_if가 이를 금지함 S s; fpoly_only(s); // 정상: enable_if가 이를 허용함 }
가능한 출력:
ContainerT is `struct Container<int>` value_type is `int`
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| CWG 1558 | C++11 |
별칭 특수화에서 사용되지 않는 인수가 치환에 참여하는지 여부가 명시되지 않음
|
치환이
수행됨 |
참고 항목
typedef
선언
|
타입에 대한 동의어를 생성함 |
| 네임스페이스 별칭 | 기존 네임스페이스의 별칭을 생성함 |