Type alias, alias template (since C++11)

From cppreference.com

Type alias is a name that refers to a previously defined type (similar to

typedef

).

Alias template is a name that refers to a family of types.

Syntax

Alias declarations are

declarations

with the following syntax:

usingidentifierattr(optional)=type-id;(1) template<template-parameter-list>usingidentifierattr(optional)=type-id;

(2) template<template-parameter-list>requiresconstraintusingidentifierattr(optional)=type-id;

(3) (since C++20)attr- optional sequence of any number of

attributes

identifier- the name that is introduced by this declaration, which becomes either a type name (1) or a template name (2)template-parameter-list-

template parameter list

, as in

template declaration

constraint- a

constraint expression

which restricts the template parameters accepted by this alias template type-id- abstract declarator or any other valid type-id (which may introduce a new type, as noted in

type-id

). The type-id cannot directly or indirectly refer to identifier. Note that the

point of declaration

of the identifier is at the semicolon following type-id. Explanation

1) A type alias declaration introduces a name which can be used as a synonym for the type denoted by type-id. It does not introduce a new type and it cannot change the meaning of an existing type name. There is no difference between a type alias declaration and

typedef

declaration. This declaration may appear in block scope, class scope, or namespace scope.

2) An alias template is a template which, when specialized, is equivalent to the result of substituting the template arguments of the alias template for the template parameters in the type-id.

template<classT>structAlloc{};template<classT>usingVec=vector<T,Alloc<T>>;// type-id is vector<T, Alloc<T>>Vec<int>v;// Vec<int> is the same as vector<int, Alloc<int>>When the result of specializing an alias template is a dependent

template-id

, subsequent substitutions apply to that template-id:

template<typename...>usingvoid_t=void;template<typenameT>void_t<typenameT::foo>f();f<int>();// error, int does not have a nested type fooThe type produced when specializing an alias template is not allowed to directly or indirectly make use of its own type:

template<classT>structA;template<classT>usingB=typenameA<T>::U;// type-id is A<T>::Utemplate<classT>structA{typedefB<T>U;};B<short>b;// error: B<short> uses its own type via A<short>::UAlias templates are never deduced by

template argument deduction

when deducing a template template parameter.

It is not possible to

partially

or

explicitly specialize

an alias template.

Like any template declaration, an alias template can only be declared at class scope or namespace scope.

The type of a

lambda expression

appearing in an alias template declaration is different between instantiations of that template, even when the lambda expression is not dependent.

template<classT>usingA=decltype([]{});// A<int> and A<char> refer to different closure types(since C++20)Notes

Feature-test macroValueStdFeature

__cpp_alias_templates

200704L

(C++11)Alias templates Keywords

using

Example

Run this code

#include<iostream>#include<string>#include<type_traits>#include<typeinfo>// type alias, identical to// typedef std::ios_base::fmtflags flags;usingflags=std::ios_base::fmtflags;// the name 'flags' now denotes a type:flagsfl=std::ios_base::dec;// type alias, identical to// typedef void (*func)(int, int);usingfunc=void(*)(int,int);// the name 'func' now denotes a pointer to function:voidexample(int,int){}funcf=example;// alias templatetemplate<classT>usingptr=T*;// the name 'ptr<T>' is now an alias for pointer to Tptr<int>x;// type alias used to hide a template parametertemplate<classCharT>usingmystring=std::basic_string<CharT,std::char_traits<CharT>>;mystring<char>str;// type alias can introduce a member typedef nametemplate<typenameT>structContainer{usingvalue_type=T;};// which can be used in generic programmingtemplate<typenameContainerT>voidinfo(constContainerT&c){typenameContainerT::value_typeT;std::cout<<"ContainerT is `"<<typeid(decltype(c)).name()<<"`\n""value_type is `"<<typeid(T).name()<<"`\n";}// type alias used to simplify the syntax of std::enable_iftemplate<typenameT>usingInvoke=typenameT::type;template<typenameCondition>usingEnableIf=Invoke<std::enable_if<Condition::value>>;template<typenameT,typename=EnableIf<std::is_polymorphic<T>>>intfpoly_only(T){return1;}structS{virtual~S(){}};intmain(){Container<int>c;info(c);// Container::value_type will be int in this function// fpoly_only(c); // error: enable_if prohibits thisSs;fpoly_only(s);// okay: enable_if allows this}Possible output:

ContainerT is `struct Container<int>` value_type is `int` Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior

CWG 1558

C++11 whether unused arguments in an alias specialization
participate in substitution was not specified substitution
is performed See also