Автоматический вывод типа с const_cast не работает
В моей работе использование const_cast
при некоторых обстоятельствах неизбежно.
Теперь я должен const_cast
некоторые довольно сложные типы, и на самом деле я не хочу писать все эти беспорядок типа в const_cast<Clutter>
выражения, особенно если Clutter
очень долго
Моей первой идеей было написать const_cast<>(myType)
, но мой компилятор не может вывести неконстантный тип myType
, Поэтому я подумал о помощи своему компилятору и разработал следующий подход, который компилируется.
#include <stdlib.h>
#include <iostream>
int main(int, char**) {
const int constVar = 6;
using T = typename std::remove_cv<decltype(constVar)>::type;
auto& var = const_cast<T&>(constVar);
var *= 2;
std::cout << &constVar << " " << &var << "\n"; // Same address!
std::cout << constVar << " " << var << "\n";
return EXIT_SUCCESS;
}
К сожалению, программа дает мне вывод 6 12
вместо ожидаемого 6 6
чего я действительно не поняла?
Что не так с моим подходом?
2 ответа
Из документации const_cast
:
const_cast
позволяет сформировать ссылку или указатель на неконстантный тип, который фактически ссылается на константный объект, или ссылку или указатель на энергонезависимый тип, который фактически ссылается на энергозависимый объект. Изменение const-объекта через неконстантный путь доступа и обращение к энергозависимому объекту через энергонезависимое glvalue приводит к неопределенному поведению.
Так что у вас есть неопределенное поведение.
Также представляет интерес эта заметка из квалификаторов типа cv.
const объект - объект, тип которого является const-квалифицированным, или неизменяемый подобъект объекта const. Такой объект нельзя изменить: попытка сделать это напрямую является ошибкой во время компиляции, а попытка сделать это косвенно (например, путем изменения объекта const посредством ссылки или указателя на неконстантный тип) приводит к неопределенному поведению.
Если у вас есть
void foo(const int& a)
{
const_cast<int&>(a) = 4;
}
затем
int a = 1;
foo(a);
совершенно законно, но
const int a = 1;
foo(a);
вызывает неопределенное поведение, потому что в foo
, a
был изначально const
,
Это полезно в некоторых случаях (обычно при взаимодействии со старой библиотекой C), но в большинстве случаев вы делаете что-то не так и должны пересмотреть свое решение.
И ответить почему const_cast<>
не вещь, я бы сказал, по двум причинам. Во-первых, когда вы делаете const_cast
Вы должны действительно знать, что делаете, если бы был разрешен какой-то шаблонный вывод, это повысило бы вероятность непреднамеренных ошибок. А во вторых const_cast
также может быть использован для удаления volatile
и как компилятор может узнать, что вы хотите отбросить?