命名空间
变体
操作

const_cast 转换

来自 cppreference.cn
< cpp‎ | 语言
 
 
C++ 语言
 
 

转换带有不同 cv 限定符的类型。

目录

[编辑] 语法

const_cast< 目标类型 >( 表达式 )

返回 目标类型 的值。

[编辑] 解释

仅允许使用 const_cast 进行以下转换

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

即使 表达式 是纯右值,也不会执行临时实质化

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

结果引用指向原始对象。

(C++17 前)

如果 表达式 是泛左值,则结果引用指向原始对象。否则,结果引用指向已实质化的临时对象

(C++17 起)

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

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

[编辑] 移除 const 属性

对于两个不同类型 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 的转换会“移除 const 属性”。

如果从类型 T1* 的纯右值到类型 T2* 的转换会移除 const 属性,则从类型 T1 的表达式到 T2 的引用的转换也会移除 const 属性。

只有 const_cast 可用于移除 const 属性。

“移除 const 属性”也意味着“移除 volatile 属性”,因为限定符转换也不能移除 volatile 属性。

[编辑] 注意

函数指针和成员函数指针不受 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++ 标准。

缺陷报告 应用于 发布时的行为 正确的行为
CWG 1965 C++11 const_cast 无法将右值引用绑定到数组纯右值 允许绑定此类引用
CWG 2879 C++17 指针纯右值操作数被实质化 它们未被实质化

[编辑] 参考

  • C++23 标准 (ISO/IEC 14882:2024)
  • 7.6.1.11 Const 转换 [expr.const.cast]
  • C++20 标准 (ISO/IEC 14882:2020)
  • 7.6.1.10 Const 转换 [expr.const.cast]
  • C++17 标准 (ISO/IEC 14882:2017)
  • 8.2.11 Const 转换 [expr.const.cast]
  • C++14 标准 (ISO/IEC 14882:2014)
  • 5.2.11 Const 转换 [expr.const.cast]
  • C++11 标准 (ISO/IEC 14882:2011)
  • 5.2.11 Const 转换 [expr.const.cast]
  • C++98 标准 (ISO/IEC 14882:1998)
  • 5.2.11 Const 转换 [expr.const.cast]
  • C++03 标准 (ISO/IEC 14882:2003)
  • 5.2.11 Const 转换 [expr.const.cast]

[编辑] 参阅