const_cast
conversion
Преобразует между типами с различной cv-квалификацией.
Содержание |
Синтаксис
const_cast<
тип-цели
>(
выражение
)
|
|||||||||
Возвращает значение типа target-type .
Объяснение
Только следующие преобразования могут быть выполнены с помощью const_cast :
T1
и
T2
, prvalue типа
T1
может быть преобразована в
T2
, если
T1
и
T2
отличаются только cv-квалификацией (формально, если, рассматривая
квалификационные декомпозиции
обоих типов, каждый
P1_i
совпадает с
P2_i
для всех
i
).
- Если expression является нулевым значением указателя, результат также является нулевым значением указателя.
- Если expression является нулевым значением указателя на член, результат также является нулевым значением указателя на член.
- Если expression указывает на объект, результат указывает на тот же объект.
- Если expression указывает за пределы объекта, результат указывает за пределы того же объекта.
- Если expression указывает на член данных, результат указывает на тот же член данных.
|
Даже если expression является prvalue, материализация временного объекта не выполняется. |
(since C++17) |
T1
и
T2
, если указатель на
T1
может быть явно преобразован к типу «указатель на
T2
» с использованием
const_cast
<
T2
*
>
, тогда следующие преобразования также могут быть выполнены:
-
Lvalue типа
T1может быть явно преобразовано в lvalue типаT2с использованием const_cast < T2 & > .
|
(начиная с C++11) |
|
Результирующая ссылка ссылается на исходный объект. |
(до C++17) |
|
Если выражение является glvalue, результирующая ссылка ссылается на исходный объект. В противном случае результирующая ссылка ссылается на материализованный временный объект . |
(начиная с C++17) |
Как и для всех выражений приведения, результат:
- lvalue, если target-type является типом lvalue-ссылки или rvalue-ссылкой на тип функции (начиная с C++11) ;
|
(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 приводит к неопределённому поведению.
Ключевые слова
Пример
#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]