Namespaces
Variants

const_cast conversion

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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

Содержание

Синтаксис

const_cast< тип-цели >( выражение )

Возвращает значение типа 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, материализация временного объекта не выполняется.

(since 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)

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

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

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

  • lvalue, если target-type является типом lvalue-ссылки или rvalue-ссылкой на тип функции (начиная с C++11) ;
  • xvalue, если target-type является rvalue-ссылкой на объектный тип;
(since 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 может использоваться для снятия константности.

«Отбрасывание константности» подразумевает «отбрасывание волатильности», так как квалификационные преобразования также не могут отбросить волатильность.

Примечания

Указатели на функции и указатели на члены функций не подлежат const_cast .

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

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

const_cast

Пример

#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; // OK, пока объект type не является const
    }
};
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++.

DR Applied to Behavior as published Correct behavior
CWG 1965 C++11 const_cast не мог связывать rvalue-ссылки с prvalue-массивами разрешено связывать такие ссылки
CWG 2879 C++17 операнды pvalue-указателей материализовывались они не материализуются

Ссылки

  • Стандарт 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]

Смотрите также