const_cast
转换
来自cppreference.com
在有不同 cv 限定的类型间转换。
语法
const_cast< 目标类型 >( 表达式 )
|
|||||||||
返回类型为 目标类型 的值。
解释
const_cast 只能进行下列转换。
1) 对于两个相似类型
T1
和 T2
,如果 T1
和 T2
仅在 cv 限定上有不同(正式而言,如果它们最长的限定性分解中每对 P1_i
和 P2_i
对于所有 i 都相同),那么 T1
类型的纯右值可以转换到 T2
。结果指代原来的实体。2) 对于两个对象类型
T1
和 T2
,如果指向 T1
的指针可以通过 const_cast<T2*> 显式转换到类型“指向 T2
的指针”,那么也可以进行以下转换:
-
T1
类型的左值可以通过 const_cast<T2&> 显式转换成类型T2
的左值。 -
T1
类型的泛左值可以通过 const_cast<T2&&> 显式转换成类型T2
的亡值。 - 如果
T1
是类类型,那么T1
类型的纯右值可以通过 const_cast<T2&&> 显式转换成类型T2
的亡值。
作为结果的引用会指代原来的对象。 |
(C++17 前) |
如果 表达式 是泛左值,那么作为结果的引用会指代原来的对象。否则作为结果的引用会指代实质化的临时量。 |
(C++17 起) |
3) 空指针值可转换成 目标类型 的空指针值。空成员指针值可转换成 目标类型 的空成员指针值。
同所有转换表达式,结果是:
- 左值,如果目标类型 是左值引用类型或到函数类型的右值引用类型 (C++11 起);
|
(C++11 起) |
- 否则是纯右值。
移除常量性
对于两个不同的类型 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
的转换会移除常量性。
如果从 T1*
类型的纯右值到类型 T2*
的转型会移除常量性,那么从 T1
类型的表达式到 T2
的引用类型的转型也会移除常量性。
只有 const_cast 能用来移除常量性。
“移除常量性”也意味着“移除易变性”,因为限定性转换同样无法移除易变性。
注解
函数指针和成员函数指针无法用于 const_cast。
const_cast 使得到非 const 类型的引用或指针能够实际指代 const 对象,或到非 volatile 类型的引用或指针能够实际指代 volatile 对象。通过非 const 访问路径修改 const 对象和通过非 volatile 泛左值涉指 volatile 对象是未定义行为。
关键词
示例
运行此代码
#include <iostream> struct type { int i; type(): i(3) {} void f(int v) const { // this->i = v; // 编译错误:this 是指向 const 的指针 const_cast<type*>(this)->i = v; // 只要该对象不是 const 就 OK } }; int main() { int i = 3; // 不声明 i 为 const const int& rci = i; const_cast<int&>(rci) = 4; // OK:修改 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 为 const [[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++23 标准(ISO/IEC 14882:2024):
- 7.6.1.11 Const cast [expr.const.cast]
- C++20 标准(ISO/IEC 14882:2020):
- 7.6.1.10 Const cast [expr.const.cast]
- C++17 标准(ISO/IEC 14882:2017):
- 8.2.11 Const cast [expr.const.cast]
- C++14 标准(ISO/IEC 14882:2014):
- 5.2.11 Const cast [expr.const.cast]
- C++11 标准(ISO/IEC 14882:2011):
- 5.2.11 Const cast [expr.const.cast]
- C++98 标准(ISO/IEC 14882:1998):
- 5.2.11 Const cast [expr.const.cast]
- C++03 标准(ISO/IEC 14882:2003):
- 5.2.11 Const cast [expr.const.cast]