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.
Contents |
[edit] Syntax
Alias declarations are block declarations with the following syntax
using identifier attr(optional) = type-id ;
|
(1) | ||||||||
template < template-parameter-list >
|
(2) | ||||||||
attr(C++11) | - | 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 |
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. |
[edit] 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.
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<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 dependent template-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 |
(since C++17) |
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 by template argument deduction when deducing a template template parameter.
It is not possible to partially or explicitly specialize an alias template.[edit] Example
Run this code
#include <string> #include <ios> #include <type_traits> // 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 fn = example; // template type alias template<class T> using ptr = T*; // the name 'ptr<T>' is now an alias for pointer to T ptr<int> x; // type alias used to hide a template parameter template <class CharT> using mystring = std::basic_string<CharT,std::char_traits<CharT>>; mystring<char> str; // type alias can introduce a member typedef name template<typename T> struct Container { using value_type = T; }; // which can be used in generic programming template<typename Container> void fn2(const Container& c) { typename Container::value_type n; } // type alias used to simplify the syntax of 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 t) { return 1; } struct S { virtual ~S() {} }; int main() { Container<int> c; fn2(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 }
[edit] See also
typedef declaration | creates a synonym for a type |