2.8 Type Aliases
2.8 类型别名
You can make using a class template more convenient by defining a new name for the whole type.
通过为整个类型定义一个新的名字,可以让类模板的使用更加方便。
Typedefs and Alias Declarations
Typedefs和别名声明(using)
To simply define a new name for a complete type, there are two ways to do it:
要简单地为完整类型定义一个新名称,有两种方法:
1. By using the keyword typedef:
1. 使用typedef关键字
typedef Stack typedef Stack<int> IntStack; // typedef void foo (IntStack const& s); // s is stack of ints IntStack istack[10]; // istack is array of 10 stacks of ints
We call this declaration a typedef and the resulting name is called a typedef-name.
我们将此声明称为typedef,并将得到的名称叫做”typedef名称”。
2. By using the keyword using (since C++11):
2.使用关键字using(从C++11起)
using IntStack = Stack <int>; // 别名声明 void foo (IntStack const& s); // s is stack of ints IntStack istack[10]; // istack is array of 10 stacks of ints
Introduced by [DosReisMarcusAliasTemplates], this is called an alias declaration.
这是由[DosReisMarcusAliasTemplates]引入,称为“别名声明”。
Note that in both cases we define a new name for an existing type rather than a new type.
注意,在以上两种情况下,我们都是为己经存在的类型定义一个新的名字,而不是定义一个新的类型。
Thus, after the typedef
因此,经过typedef之后
typedef Stack <int> IntStack;
or
或者
using IntStack = Stack <int>;
IntStack and Stack<int> are two interchangeable notations for the same type.
IntStack和Stack<int>是同一类型的两个可互换的符号。
As a common term for both alternatives to define a new name for an existing type, we use the term type alias declaration. The new name is a type alias then.
作为两个替代方案的通用术语,为现有类型定义新名称,我们称之为“类型别名声明”。
Because it is more readable (always having the defined type name on the left side of the =), for the remainder of this book, we prefer the alias declaration syntax when declaring an type alias.
因为它更具可读性(经常将定义的类型名称放在“=”等号左边)。对于本书的其余部分,当声明一个类型别名时,我们更喜欢使用“别名声明”语法。
Alias Templates
别名模板
Unlike a typedef, an alias declaration can be templated to provide a convenient name for a family of types. This is also available since C++11 and is called an alias template.
与typedef不同,别名声明(using)可以被模板化,以便为类型族提供方便的名称。从C++11开始提供该功能,我们称之为“别名模板”。
The following alias template DequeStack, parameterized over the element type T, expands to a Stack that stores its elements in a std::deque:
下面的DequeStack别名模板(在元素类型T上参数化),扩展到一个栈。该栈将其元素存储在std::queue中:
template<typename T>
using DequeStack = Stack<T, std::deque<T>>;
Thus, both class templates and alias templates can be used as a parameterized type.
因此,类模板和别名模板都可以作为一个将被参数化的类型。
But again, an alias template simply gives a new name to an existing type, which can still be used. Both DequeStack<int> and Stack<int, std::deque<int>> represent the same type.
但是同样,别名模板只是简单地为一个己经存在的类型起个新名字。该名字仍可以使用。DequeStack<int>和Stack<int, std::deque<int>>表示相同的类型。
Note again that, in general, templates can only be declared and defined in global/namespace scope or inside class declarations.
再次注意,通常,模板只能在全局/名称空间作域或者类内部声明。
Alias Templates for Member Types
成员类型的别名模板
Alias templates are especially helpful to define shortcuts for types that are members of class templates. After
别名模板对于定义类函数成员的快捷定义特别有用。之后:
struct C { typedef … iterator; … };
or:
或者
struct MyType { using iterator = …; … };
a definition such as
如下的定义:
template<typename T>
using MyTypeIterator = typename MyType<T>::iterator;
allows the use of
允许使用
MyTypeIterator< int> pos;
instead of the following:
来代替下面的:
typename MyType<T>::iterator pos;
Type Traits Suffix_t
类型萃取后缀_t
Since C++14, the standard library uses this technique to define shortcuts for all type traits in the standard library that yield a type. For example, to be able to write
从C++14开始,标准库使用一项快捷定义所有类型萃取的技术来产生一个类型。例如,可以用
std::add_const_t<T> // 从C++14开始
instead of
来替换
typename std::add_const<T>::type // 从 C++11开始
the standard library defines:
标准库定义:
namespace std { template<typename T> using add_const_t = typename add_const<T>::type; }