Spec-Zone.ru › C++

const_cast преобразование

Преобразует типы с различными cv-квалификациями.

Синтаксис

const_cast< target-type >( expression )

Возвращает значение типа target-type.

Пояснение

С помощью const_cast можно выполнить только следующие преобразования:

1) Для двух сходных типов указателей на объект или указателей на член данных T1 и T2 prvalue типа T1 можно преобразовать в T2, если T1 и T2 различаются только cv-квалификацией (формально, если при рассмотрении декомпозиций квалификаций обоих типов каждый P1_i совпадает с P2_i для всех i).
  • Если expression является нулевым указателем, результатом также является нулевой указатель.
  • Если expression является нулевым указателем на член, результатом также является нулевой указатель на член.
  • Если expression указывает на объект, результат указывает на тот же объект.
  • Если expression указывает за пределы объекта, результат указывает за пределы того же объекта.
  • Если expression указывает на член данных, результат указывает на тот же член данных.

Даже если expression является prvalue, материализация временного объекта не выполняется.

(начиная с C++17)
2) Для двух объектных типов T1 и T2, если указатель на T1 можно явно преобразовать к типу «указатель на T2» с помощью const_cast<T2*>, также можно выполнить следующие преобразования:
  • lvalue типа T1 можно явно преобразовать в lvalue типа T2 с помощью const_cast<T2&>.
  • glvalue типа T1 можно явно преобразовать в xvalue типа T2 с помощью const_cast<T2&&>.
  • Если T1 является типом класса или массива, prvalue типа T1 можно явно преобразовать в xvalue типа T2 с помощью const_cast<T2&&>.
(начиная с C++11)

Полученная ссылка ссылается на исходный объект.

(до C++17)

Если expression является glvalue, полученная ссылка ссылается на исходный объект. В противном случае полученная ссылка ссылается на материализованный временный объект.

(начиная с C++17)

Как и для всех выражений приведения, результат является:

  • lvalue, если target-type является типом ссылки на lvalue или ссылкой rvalue на тип функции(начиная с C++11);
  • xvalue, если target-type является ссылкой rvalue на объектный тип;
(начиная с C++11)
  • в противном случае — prvalue.

Снятие константности

Для двух различных типов 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).

Если приведение prvalue типа T1* к типу T2* снимает константность, то приведение выражения типа T1 к ссылке на T2 также снимает константность.

Для снятия константности можно использовать только const_cast.

«Снятие константности» подразумевает «снятие volatile-квалификации», поскольку преобразования квалификаций также не могут снимать volatile-квалификацию.

Примечания

На указатели на функции и указатели на функции-члены const_cast не распространяется.

const_cast позволяет получить ссылку или указатель на неконстантный тип, который фактически ссылается на константный объект, либо ссылку или указатель на невольатильный тип, который фактически ссылается на volatile-объект. Изменение константного объекта через неконстантный путь доступа и обращение к volatile-объекту через невольатильный glvalue приводит к неопределённому поведению.

Ключевые слова

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 не мог привязывать ссылки rvalue к prvalue массивов разрешено привязывать такие ссылки
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]

См. также

  • static_cast
  • dynamic_cast
  • reinterpret_cast
  • явное приведение
  • неявные преобразования

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/const_cast

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API