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) |
T1 и T2, если указатель на T1 можно явно преобразовать к типу «указатель на T2» с помощью const_cast<T2*>, также можно выполнить следующие преобразования: - lvalue типа
T1можно явно преобразовать в lvalue типаT2с помощьюconst_cast<T2&>.
| (начиная с C++11) |
| Полученная ссылка ссылается на исходный объект. | (до C++17) |
| Если expression является glvalue, полученная ссылка ссылается на исходный объект. В противном случае полученная ссылка ссылается на материализованный временный объект. | (начиная с C++17) |
Как и для всех выражений приведения, результат является:
- lvalue, если target-type является типом ссылки на lvalue или ссылкой rvalue на тип функции(начиная с C++11);
| (начиная с 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 приводит к неопределённому поведению.
Ключевые слова
Пример
#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]
См. также
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/const_cast