Насколько мне известно (и эта тема: Когда следует использовать static_cast, dynamic_cast, const_cast и reinterpret_cast?), const_cast - единственное приведение, которое должно иметь возможность убирать постоянство переменной. Однако, возясь с clang-6.0 и g++5.4.0, я наткнулся на поведение, которое противоречило бы сказанному выше. Похоже, static_cast выполняет ту же работу.
Эти основные функции дают одинаковые результаты с обоими компиляторами:
определение тестового класса
struct Base {
Base() {
std::cout << "Base::Base()\n";
}
void test() const {
std::cout << "Base::test()\n";
}
void no_const() {
std::cout << "Base::no_const()\n";
}
virtual ~Base() = default;
};
с const_cast
int main(void) {
std::cout << "BEGIN\n";
const Base b;
const_cast<Base&>(b).no_const();
std::cout << "END\n";
}
с static_cast
int main(void) {
std::cout << "BEGIN\n";
const Base b;
static_cast<Base>(b).no_const();
std::cout << "END\n";
}
Результат:
BEGIN
Base::Base()
Base::no_const()
END
Что дает?





Добавьте определение конструктора копирования для Base, оно ответит на ваш вопрос.
Base(Base const&) {
std::cout << "Base::Base(Base const&)\n";
}
Результат вашего второго примера изменится на
BEGIN
Base::Base()
Base::Base(Base const&)
Base::no_const()
END
Попытайтесь отбросить константность от самого b, и вы увидите ошибку
static_cast<Base&>(b).no_const();
// ^
error: invalid
static_castfrom type 'const Base' to type 'Base&'static_cast<Base&>(b).no_const();
А, конструктор копирования - это строительный блок, который я забыл. Мне стыдно! Большое спасибо!
Вы играете в ловкость рук. Эти два преобразования не похожи друг на друга - один относится к ссылке
Base&, другой - кBase- это включает создание временной копии; он не отменяет неизменности оригинала. Если вы попробуетеstatic_cast<Base&>(b), вы получите ожидаемую ошибку.