const_cast
conversion
在不同 cv 限定类型之间进行转换。
目录 |
语法
const_cast<
目标类型
>(
表达式
)
|
|||||||||
返回类型为 target-type 的值。
说明
只有以下转换可以通过 const_cast 实现:
T1
和
T2
,若
T1
和
T2
仅因 cv 限定符不同(形式化地说,若考虑两者的
限定符分解
,每个
P1_i
与
P2_i
对所有
i
均相同),则类型
T1
的纯右值可转换为
T2
。
- 若 expression 是空指针值,结果也是空指针值。
- 若 expression 是空成员指针值,结果也是空成员指针值。
- 若 expression 指向某个对象,结果指向同一对象。
- 若 expression 指向某对象末尾之后的位置,结果指向同一对象末尾之后的位置。
- 若 expression 指向某个数据成员,结果指向同一数据成员。
|
即使 expression 是纯右值,也不会执行 临时物化 。 |
(since C++17) |
T1
和
T2
,如果指向
T1
的指针可以通过
const_cast
<
T2
*
>
显式转换为“指向
T2
的指针”类型,则还可以进行以下转换:
-
类型为
T1的左值可以通过 const_cast < T2 & > 显式转换为类型为T2的左值。
|
(C++11 起) |
|
结果引用指向原始对象。 |
(C++17 前) |
|
如果 表达式 是泛左值,则结果引用指向原始对象。否则,结果引用指向 实质化的临时对象 。 |
(C++17 起) |
与所有强制转换表达式一样,结果是:
- 若 target-type 是左值引用类型 或函数类型的右值引用 (C++11 起) ,则为左值;
|
(since C++11) |
- 否则为纯右值。
去除 const 限定
对于两个不同的类型
T1
和
T2
,从
T1
到
T2
的转换
会抛弃常量性
的条件是:存在
T2
的
限定分解
形式为“cv2_0 P2_0 cv2_1 P2_1 ... cv2_n−1 P2_n−1 cv2_n U2”,且不存在任何能将
T1
转换为“cv2_0 P1_0 cv2_1 P1_1 ... cv2_n−1 P1_n−1 cv2_n U1”(相同的 cv 限定符组件,不同的 P 组件和 U 组件)的
限定转换
。
如果从类型
T1*
的纯右值到类型
T2*
的转换会抛弃 const 限定,那么从类型
T1
的表达式到
T2
引用的转换同样会抛弃 const 限定。
只有 const_cast 可用于去除常量性。
“抛弃常量性”意味着“抛弃易变性”,因为限定转换同样无法抛弃易变性。
注释
指向函数的指针和指向成员函数的指针不受 const_cast 约束。
const_cast 使得可以形成指向非 const 类型的引用或指针,而该引用或指针实际上指向的是 const 对象 ;或者形成指向非 volatile 类型的引用或指针,而该引用或指针实际上指向的是 volatile 对象 。通过非 const 访问路径修改 const 对象,或通过非 volatile glvalue 引用 volatile 对象会导致未定义行为。
关键词
示例
#include <iostream> struct type { int i; type(): i(3) {} void f(int v) const { // this->i = v; // 编译错误:this 是指向常量的指针 const_cast<type*>(this)->i = v; // 只要 type 对象不是常量就可行 } }; int main() { int i = 3; // i 未声明为常量 const int& rci = i; const_cast<int&>(rci) = 4; // 可行:修改 i std::cout << "i = " << i << '\n'; type t; // 如果这是 const type t,则 t.f(4) 将是未定义行为 t.f(4); std::cout << "type::i = " << t.i << '\n'; const int j = 3; // j 被声明为常量 [[maybe_unused]] int* pj = const_cast<int*>(&j); // *pj = 4; // 未定义行为 [[maybe_unused]] void (type::* pmf)(int) const = &type::f; // 成员函数指针 // const_cast<void(type::*)(int)>(pmf); // 编译错误:const_cast 不能 // 用于函数指针 }
输出:
i = 4 type::i = 4
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 适用范围 | 发布时行为 | 正确行为 |
|---|---|---|---|
| CWG 1965 | C++11 | const_cast 无法将右值引用绑定到数组纯右值 | 允许绑定此类引用 |
| CWG 2879 | C++17 | 指针纯右值操作数会被实质化 | 不进行实质化处理 |
参考文献
- C++23 标准 (ISO/IEC 14882:2024):
-
- 7.6.1.11 常量转换 [expr.const.cast]
- C++20 标准 (ISO/IEC 14882:2020):
-
- 7.6.1.10 常量转换 [expr.const.cast]
- C++17 标准 (ISO/IEC 14882:2017):
-
- 8.2.11 常量转换 [expr.const.cast]
- C++14 标准 (ISO/IEC 14882:2014):
-
- 5.2.11 常量转换 [expr.const.cast]
- C++11 标准 (ISO/IEC 14882:2011):
-
- 5.2.11 常量转换 [expr.const.cast]
- C++98 标准 (ISO/IEC 14882:1998):
-
- 5.2.11 常量转换 [expr.const.cast]
- C++03 标准 (ISO/IEC 14882:2003):
-
- 5.2.11 常量转换 [expr.const.cast]