命名空间
变体
操作

const_cast 转换

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
通用主题
流程控制
条件执行语句
if
迭代语句(循环)
for
范围 for (C++11)
跳转语句
函数
函数声明
Lambda 函数表达式
inline 说明符
动态异常规范 (直到 C++17*)
noexcept 说明符 (C++11)
异常
命名空间
类型
说明符
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
存储期说明符
初始化
 
 

在具有不同 cv 限定的类型之间转换。

目录

[编辑] 语法

const_cast< target-type >( expression )

返回 target-type 类型的值。

[编辑] 解释

只有以下转换可以使用 const_cast 完成

1) 对于两个相似的对象指针或指向数据成员类型的指针 T1T2,如果 T1T2 仅在 cv 限定上有所不同,则可以将 T1 类型的纯右值转换为 T2 类型(形式上,如果考虑两种类型的限定分解,则对于所有 i,每个 P1_iP2_i 相同)。
  • 如果 expression 是空指针值,则结果也为空指针值。
  • 如果 expression 是空成员指针值,则结果也为空成员指针值。
  • 如果 expression 指向一个对象,则结果指向同一个对象。
  • 如果 expression 指向对象之后的位置,则结果指向同一个对象之后的位置。
  • 如果 expression 指向数据成员,则结果指向同一个数据成员。

即使 expression 是纯右值,也不会执行临时量实质化

(自 C++17 起)
2) 对于两个对象类型 T1T2,如果可以使用 const_cast<T2*> 将指向 T1 的指针显式转换为 “指向 T2 的指针” 类型,那么也可以进行以下转换
  • 可以使用 const_cast<T2&>T1 类型的左值显式转换为 T2 类型的左值。
  • 可以使用 const_cast<T2&&>T1 类型的泛左值显式转换为 T2 类型的将亡值。
  • 如果 T1 是类或数组类型,则可以使用 const_cast<T2&&>T1 类型的纯右值显式转换为 T2 类型的将亡值。
(自 C++11 起)

结果引用指代原始对象。

(直到 C++17)

如果 expression 是泛左值,则结果引用指代原始对象。否则,结果引用指代实质化的临时量

(自 C++17 起)

与所有转型表达式一样,结果是

  • 如果 target-type 是左值引用类型或函数类型的右值引用(自 C++11 起),则为左值;
  • 如果 target-type 是对象类型的右值引用,则为将亡值;
(自 C++11 起)
  • 否则为纯右值。

[编辑] 去除常量性

对于两种不同的类型 T1T2,如果存在 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 组件),则从 T1T2 的转换去除常量性

如果从 T1* 类型的纯右值到 T2* 类型的转型去除常量性,则从 T1 类型的表达式到 T2 类型的引用的转型也将去除常量性。

只有 const_cast 可以用于去除常量性。

“去除常量性” 意味着 “去除易变性”,因为限定转换也不能去除易变性。

[编辑] 注解

指向函数的指针和指向成员函数的指针不受 const_cast 的约束。

const_cast 使得形成对非 const 类型的引用或指针成为可能,而实际上它引用的是 const 对象,或者形成对非 volatile 类型的引用或指针成为可能,而实际上它引用的是 volatile 对象。通过非 const 访问路径修改 const 对象,以及通过非 volatile 泛左值 引用 volatile 对象,会导致未定义行为。

[编辑] 关键词

const_cast

[编辑] 示例

#include <iostream>
 
struct type
{
    int i;
 
    type(): i(3) {}
 
    void f(int v) const
    {
        // this->i = v;                 // compile error: this is a pointer to const
        const_cast<type*>(this)->i = v; // OK as long as the type object isn't const
    }
};
 
int main()
{
    int i = 3;                 // i is not declared const
    const int& rci = i;
    const_cast<int&>(rci) = 4; // OK: modifies i
    std::cout << "i = " << i << '\n';
 
    type t; // if this was const type t, then t.f(4) would be undefined behavior
    t.f(4);
    std::cout << "type::i = " << t.i << '\n';
 
    const int j = 3; // j is declared const
    [[maybe_unused]]
    int* pj = const_cast<int*>(&j);
    // *pj = 4;      // undefined behavior
 
    [[maybe_unused]]
    void (type::* pmf)(int) const = &type::f; // pointer to member function
    // const_cast<void(type::*)(int)>(pmf);   // compile error: const_cast does
                                              // not work on function pointers
}

输出

i = 4
type::i = 4

[编辑] 缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

DR 应用于 已发布行为 正确行为
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]

[编辑] 参见