命名空间
变体
操作

类型别名,别名模板 (C++11 起)

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句 (循环)
for
范围 for (C++11 起)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (直至 C++17*)
noexcept 说明符 (C++11 起)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11 起)
auto (C++11 起)
constexpr (C++11 起)
consteval (C++20)
constinit (C++20)
存储期说明符
初始化
表达式
替代表现形式
字面量
布尔 - 整数 - 浮点
字符 - 字符串 - nullptr (C++11 起)
用户定义 (C++11 起)
实用工具
特性 (C++11 起)
类型
typedef 声明
类型别名声明 (C++11 起)
类型转换
内存分配
类特有的函数属性
虚函数
override 说明符 (C++11 起)  
final 说明符 (C++11 起)
explicit (C++11 起)
static

特殊成员函数
模板
模板特化
形参包 (C++11 起)
杂项
 
 

类型别名是指代先前定义类型的名称(类似于 typedef)。

别名模板是指代一系列类型的名称。

内容

[编辑] 语法

别名声明是具有以下语法的声明

using identifier attr (optional) = type-id ; (1)
template < template-parameter-list >

using identifier attr (optional) = type-id ;

(2)
template < template-parameter-list > requires constraint

using identifier attr (optional) = type-id ;

(3) (C++20 起)
attr - 任意数量特性的可选序列
identifier - 由此声明引入的名称,它会成为类型名称 (1) 或模板名称 (2)
template-parameter-list - 模板形参列表,如同模板声明中一样
constraint - 约束表达式,用于限制此别名模板接受的模板形参
type-id - 抽象声明符或任何其他有效的 type-id(可能引入新类型,如 type-id 中所述)。type-id 不能直接或间接引用 identifier。请注意,identifier 的声明点位于 type-id 后的分号处。

[编辑] 解释

1) 类型别名声明引入一个名称,该名称可用作 type-id 所表示类型的同义词。它不会引入新类型,也不能更改现有类型名称的含义。类型别名声明和 typedef 声明之间没有区别。此声明可以出现在块作用域、类作用域或命名空间作用域中。
2) 别名模板是一个模板,当特化时,它等效于将别名模板的模板实参替换为 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>>

当特化别名模板的结果是依赖的 template-id 时,后续替换将应用于该 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

特化别名模板时产生的类型不允许直接或间接使用其自身的类型

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

当推导模板模板形参时,永远不会通过模板实参推导来推导别名模板。

无法部分显式特化别名模板。

与任何模板声明一样,别名模板只能在类作用域或命名空间作用域中声明。

即使 lambda 表达式不依赖,出现在别名模板声明中的 lambda 表达式的类型在该模板的实例化之间也不同。

template<class T>
using A = decltype([] {}); // A<int> and A<char> refer to different closure types
(C++20 起)

[编辑] 注解

特性测试宏 标准 特性
__cpp_alias_templates 200704L (C++11) 别名模板

[编辑] 关键字

using

[编辑] 示例

#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 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 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_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) { return 1; }
 
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
}

可能的输出

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

[编辑] 缺陷报告

以下行为变更缺陷报告已追溯应用于先前发布的 C++ 标准。

缺陷报告 应用于 已发布行为 正确行为
CWG 1558 C++11 别名特化中未使用的实参是否
参与替换未指定
替换
已执行

[编辑] 参见

typedef 声明 为类型创建同义词[编辑]
命名空间别名 为现有命名空间创建别名[编辑]