显式类型转换

来自cppreference.com
< cpp‎ | language

用显式和隐式转换的组合进行类型之间的转换。

语法

( 新类型 ) 表达式 (1)
新类型 ( 表达式 ) (2)
新类型 ( 表达式列表 ) (3)
新类型 ( ) (4)
新类型 { 表达式列表(可选) } (5) (C++11 起)
模板名 ( 表达式列表(可选) ) (6) (C++17 起)
模板名 { 表达式列表(可选) } (7) (C++17 起)
auto ( 表达式 ) (8) (C++23 起)
auto { 表达式 } (9) (C++23 起)

返回 新类型 类型的值。

解释

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),但首先进行类模板实参推导
8,9) auto 说明符被分别替换成以 auto x(expr); (决不转译成函数声明)或 auto x{expr}; 声明的变量 x 的被推导类型。结果始终为对象类型的纯右值。

同所有转型表达式,结果是:

  • 左值,如果 新类型 是左值引用或到函数类型的右值引用;
  • 亡值,如果 新类型 是到对象类型的右值引用;
  • 否则为纯右值。

示例

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++20 标准(ISO/IEC 14882:2020):
  • 7.6.1.4 Explicit type conversion (functional notation) [expr.type.conv]
  • 7.6.3 Explicit type conversion (cast notation) [expr.cast]
  • C++17 标准(ISO/IEC 14882:2017):
  • 8.2.3 Explicit type conversion (functional notation) [expr.type.conv]
  • 8.4 Explicit type conversion (cast notation) [expr.cast]
  • C++14 标准(ISO/IEC 14882:2014):
  • 5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
  • 5.4 Explicit type conversion (cast notation) [expr.cast]
  • C++11 标准(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++03 标准(ISO/IEC 14882:2003):
  • 5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
  • 5.4 Explicit type conversion (cast notation) [expr.cast]
  • C++98 标准(ISO/IEC 14882:1998):
  • 5.2.3 Explicit type conversion (functional notation) [expr.type.conv]
  • 5.4 Explicit type conversion (cast notation) [expr.cast]

参阅

const_cast 转换 添加或移除 const
static_cast 转换 进行基本转换
dynamic_cast 转换 进行有检查的多态转换
reinterpret_cast 转换 进行通用低层转换
标准转换 从一个类型到另一类型的隐式转换