用显式和隐式转换的组合进行类型之间的转换。
语法
( 新类型 ) 表达式 | (1) | |
新类型 ( 表达式 ) | (2) | |
新类型 ( 表达式列表 ) | (3) | |
新类型 ( ) | (4) | |
新类型 { 表达式列表(可选) } | (5) | (C++11 起) |
模板名 ( 表达式列表(可选) ) | (6) | (C++17 起) |
模板名 { 表达式列表(可选) } | (7) | (C++17 起) |
返回 新类型 类型的值。
解释
1) 遇到 C 风格转型表达式时,编译器尝试将它解释成下列转型表达式,以此顺序:
a) const_cast
<新类型>(表达式);
b) static_cast
<新类型>(表达式),带扩展:额外允许将到派生类的指针或引用转型成到无歧义基类的指针或引用(反之亦然),纵使基类不可访问也是如此(即此转型忽略 private 继承说明符)。同样适用于将成员指针转型为指向无歧义非虚基类的成员的指针;
c) static_cast(带扩展)后随 const_cast;
d) reinterpret_cast
<新类型>(表达式);
e) reinterpret_cast 后随 const_cast。
选择首个满足相应转型运算符要求的方式,即便它无法编译(见示例)。若转型能解释成多于一种 static_cast
后随 const_cast
的方式,则它无法编译。
另外,C 风格转型写法允许在不完整类型的指针之间进行双向转型。若 表达式 与 新类型 是指向不完整类型的指针,则选用 static_cast 还是 reinterpret_cast 是未指明的。
2) 函数式转型表达式由一个简单类型说明符或一个 typedef 说明符构成(换言之,它是单个单词的类型名:unsigned int(表达式) 或 int*(表达式) 非法),后随带括号的单个表达式。此转型表达式准确等价于对应的 C 风格转型表达式。
3) 若括号中有多于一个表达式,则 新类型 必须是带有适当声明的构造函数的类。此表达式是 新类型 类型的纯右值,其指代的临时量 (C++17 前)其结果对象 (C++17 起)以 表达式列表 直接初始化。
4) 若 新类型 指名一个非数组完整对象类型,则此表达式是 新类型 类型的纯右值,指代该类型临时量 (C++17 前)其结果对象为该类型(可能添加 cv 限定符) (C++17 起)。若 新类型 是对象类型,则对象被值初始化。若 新类型 是(可有 cv 限定的)void
,则表达式是 void 纯右值而无结果对象 (C++17 起)。
5) 单个单词的类型名后随花括号初始化器列表,是指定类型的纯右值,其指代的临时量 (C++17 前)其结果对象 (C++17 起)以指定的花括号初始化器列表直接列表初始化。若 新类型 是(可有 cv 限定的)void
,则表达式是 void 纯右值而无结果对象 (C++17 起)。这是仅有的能创建数组纯右值的表达式。
6,7) 同 (2-5),但首先进行类模板实参推导,
同所有转型表达式,结果是:
- 左值,若 new_type 是左值引用或到函数类型的右值引用;
- 亡值,若 new_type 是到对象类型的右值引用;
- 否则为纯右值。
示例
运行此代码
- double f = 3.14;
- unsigned int n1 = (unsigned int)f; // C 风格转型
- unsigned int n2 = unsigned(f); // 函数式转型
- class C1;
- class C2;
- C2* foo(C1* p)
- {
- return (C2*)p; // 转型不完整类型到不完整类型
- }
- // 此示例中,C 风格转型被转译成 static_cast
- // 尽管它也能作为 reinterpret_cast 工作
- struct A {};
- struct I1 : A {};
- struct I2 : A {};
- struct D : I1, I2 {};
- int main()
- {
- D* d = nullptr;
- // A* a = (A*)d; // 编译时错误
- A* a = reinterpret_cast<A*>(d); // 这能编译
- }
引用
- C++11 standard (ISO/IEC 14882:2011):
- 5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
- 5.4 Explicit type conversion (cast notation) [expr.cast]
- C++98 standard (ISO/IEC 14882:1998):
- 5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
- 5.4 Explicit type conversion (cast notation) [expr.cast]