本文介绍 C++ 中的类型转换。
涉及 type 的一些概念
Incomplete type
- void 以及其 cv-qualified 形式
- incompletely-defined object type
一个 class 被声明(比如一个前向声明),却没有定义。
bound 未知的数组。
imcomplete type 构成的数组。
enum,从它的声明,到它的 underlying type 被确定期间。
这里说明一下,bound 未知的数组未必是 flex 数组。它可能是如下面这种 extern 形式定义的
1 | extern int x[]; // the type of x is "array of unknown bound of int" |
在下列情况下,需要类型是 Complete 的:
- TODO
typd-id
我们可以通过 class/union/enum/typedef/using(type alias) 这些方式定义一个具名的类型。但是在 C++ 中,我们经常使用那些不具名的类型,例如下面的情况。
1 | int* p; // declaration of a pointer to int |
此外,RTTI 机制还提供了一个 typeid 运算符(不是函数)
1 | int main() { |
显式类型转换
显式转换有几种类型:
(new-type) expr
型。这是 C-style 的,C++ 会按顺序尝试:
- const_cast
- static_cast(增强的)
注意,子类的指针或者引用,可以被转成无歧义的基类,即使基类不可访问。对于成员函数的指针也同样适用 - static_cast(增强的) + const_cast
- reinterpret_cast
- reinterpret_cast + const_cast
new-type (expr)
型。
需要注意,这种 function-style cast expression 容易和声明产生歧义。此时,这些歧义都会被视作声明。
1 | struct M {}; |
【C++11起】new-type {expr}
型。
一个显式类型转换的类型是什么呢?
- 对于 lvalue reference,结果是一个 lvalue
- 对于函数的 rvalue reference,结果是一个 lvalue
- 对于 rvalue reference,结果是一个 xvalue
- 对于其他情况,结果是一个 prvalue