General topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
Iteration statements (loops) | ||||||||||||||||
Jump statements | ||||||||||||||||
Functions | ||||||||||||||||
Function declaration | ||||||||||||||||
Lambda function expression | ||||||||||||||||
inline specifier | ||||||||||||||||
Dynamic exception specifications(until C++17*) | ||||||||||||||||
noexcept specifier(C++11) | ||||||||||||||||
Exceptions | ||||||||||||||||
Namespaces | ||||||||||||||||
Types | ||||||||||||||||
Specifiers | ||||||||||||||||
| ||||||||||||||||
Storage duration specifiers | ||||||||||||||||
Initialization | ||||||||||||||||
Expressions | ||||||||||||||||
Alternative representations | ||||||||||||||||
Literals | ||||||||||||||||
Boolean -Integer -Floating-point | ||||||||||||||||
Character -String -nullptr(C++11) | ||||||||||||||||
User-defined(C++11) | ||||||||||||||||
Utilities | ||||||||||||||||
Attributes(C++11) | ||||||||||||||||
Types | ||||||||||||||||
typedef declaration | ||||||||||||||||
Type alias declaration(C++11) | ||||||||||||||||
Casts | ||||||||||||||||
Memory allocation | ||||||||||||||||
Classes | ||||||||||||||||
Class-specific function properties | ||||||||||||||||
| ||||||||||||||||
Special member functions | ||||||||||||||||
Templates | ||||||||||||||||
Miscellaneous | ||||||||||||||||
|
|
Type alias is a name that refers to a previously defined type (similar totypedef
).
Alias template is a name that refers to a family of types.
Contents |
Alias declarations aredeclarations with the following syntax:
using identifierattr (optional)= type-id; | (1) | ||||||||
template < template-parameter-list>
| (2) | ||||||||
template < template-parameter-list> requires constraint
| (3) | (since C++20) | |||||||
attr | - | optional sequence of any number ofattributes |
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 intemplate declaration |
constraint | - | aconstraint expression which restricts the template parameters accepted by this alias template |
type-id | - | abstract declarator or any other validtype-id (which may introduce a new type, as noted intype-id). Thetype-id cannot directly or indirectly refer toidentifier. Note that thepoint of declaration of the identifier is at the semicolon followingtype-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>>
When the result of specializing an alias template is a dependenttemplate-id, subsequent substitutions apply to that 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
The type produced when specializing an alias template is not allowed to directly or indirectly make use of its own type:
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 templates are never deduced bytemplate argument deduction when deducing a template template parameter.
It is not possible topartially orexplicitly specialize an alias template.Like any template declaration, an alias template can only be declared at class scope or namespace scope.
The type of alambda expression appearing in an alias template declaration is different between instantiations of that template, even when the lambda expression is not dependent. template<class T>using A= decltype([]{});// A<int> and A<char> refer to different closure types | (since C++20) |
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_alias_templates | 200704L | (C++11) | Alias templates |
#include <iostream>#include <string>#include <type_traits>#include <typeinfo> // type alias, identical to// typedef std::ios_base::fmtflags flags;using flags=std::ios_base::fmtflags;// the name 'flags' now denotes a type:flags fl=std::ios_base::dec; // type alias, identical to// typedef void (*func)(int, int);using func=void(*)(int,int); // the name 'func' now denotes a pointer to function:void example(int,int){}func f= example; // alias templatetemplate<class T>using ptr= T*;// the name 'ptr<T>' is now an alias for pointer to Tptr<int> x; // type alias used to hide a template parametertemplate<class CharT>using mystring=std::basic_string<CharT,std::char_traits<CharT>>; mystring<char> str; // type alias can introduce a member typedef nametemplate<typename T>struct Container{using value_type= T;}; // which can be used in generic programmingtemplate<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";} // type alias used to simplify the syntax of std::enable_iftemplate<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){return1;} struct S{virtual ~S(){}}; int main(){ Container<int> c; info(c);// Container::value_type will be int in this function// fpoly_only(c); // error: enable_if prohibits this S s; fpoly_only(s);// okay: enable_if allows this}
Possible output:
ContainerT is `struct Container<int>`value_type is `int`
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 |
typedef declaration | creates a synonym for a type[edit] |
namespace alias | creates an alias of an existing namespace[edit] |