const_cast
转换
来自cppreference.com
在有不同 cv 限定的类型间转换。
目录 |
[编辑]语法
const_cast< 目标类型>( 表达式) | |||||||||
返回类型为目标类型 的值。
[编辑]解释
const_cast 只能进行下列转换:
1) 对于两个相似的对象指针或数据成员指针类型
T1
和 T2
,如果 T1
和 T2
仅在 cv 限定上有不同(正式而言,如果它们最长的限定性分解中每对 P1_i
和 P2_i
对于所有 i 都相同),那么 T1
类型的纯右值可以转换到 T2
。 - 如果表达式 是空指针值,那么结果也是空指针值。
- 如果表达式 是空成员指针值,那么结果也是空成员指针值。
- 如果表达式 指向某个对象,那么结果也指向该对象。
- 如果表达式 指向某个对象尾后,那么结果也指向该对象尾后。
- 如果表达式 指向某个数据成员,那么结果也指向同一个数据成员。
即使表达式 是纯右值,也不会进行临时量实质化。 | (C++17 起) |
2) 对于两个对象类型
T1
和 T2
,如果指向 T1
的指针可以通过 const_cast<T2*> 显式转换到类型“指向 T2
的指针”,那么也可以进行以下转换: T1
类型的左值可以通过 const_cast<T2&> 显式转换成类型T2
的左值。
| (C++11 起) |
作为结果的引用会指代原来的对象。 | (C++17 前) |
如果表达式 是泛左值,那么作为结果的引用会指代原来的对象。否则作为结果的引用会指代实质化的临时量。 | (C++17 起) |
同所有转换表达式,结果是:
- 左值,如果目标类型 是左值引用类型或到函数类型的右值引用类型(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 为 constconstint& rci = i;const_cast<int&>(rci)=4;// OK:修改 istd::cout<<"i = "<< i <<'\n'; type t;// 如果这是 const type t,那么 t.f(4) 会是未定义行为 t.f(4);std::cout<<"type::i = "<< t.i<<'\n'; constint 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++ 标准。
缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
---|---|---|---|
CWG 1965 | C++11 | const_cast 无法将右值引用绑定到数组右值 | 允许绑定此类引用 |
CWG 2879 | C++17 | 指针纯右值操作数会被实质化 | 它们不会被实质化 |
[编辑]引用
- 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]