alias template
类型别名,别名模板%28,因为C++11%29
类型别名是引用先前定义的类型%28的名称,类似于胡枝子f29%。
别名模板是指类型系列的名称。
句法
别名声明是声明使用以下语法:
using identifier attr(optional) = type-id ; | (1) | |
---|---|---|
template < template-parameter-list > using identifier attr(optional) = type-id ; | (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. |
解释
1%29类型别名声明引入了一个名称,该名称可用作由type-id表示的类型的同义词。它不引入新类型,也不能更改现有类型名称的含义。类型别名声明与胡枝子f申报。此声明可能出现在块作用域、类作用域或命名空间范围中。
2%29别名模板是一个模板,当它专门化时,它相当于将别名模板的模板参数替换为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 | (since C++14) |
---|
在专门化别名模板时生成的类型不允许直接或间接地使用其自己的类型:
二次
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
二次
别名模板永远不会由模板参数推导在推导模板模板参数时。不可能部分或显式专业化别名模板。
与任何模板声明一样,别名模板只能在类范围或命名空间范围内声明。
例
二次
#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 f = example;
// alias template
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 g(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;
g(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
}
二次
缺陷报告
以下行为更改缺陷报告追溯应用于先前发布的C++标准。
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 1558 | C++14 | whether unused arguments in an alias specialization participate in substitition is not specified | substitution is performed |
另见
typedef declaration | creates a synonym for a type |
---|
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。