Автоматический вывод типа с 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 и как компилятор может узнать, что вы хотите отбросить?

Другие вопросы по тегам