dcl.type.cv предоставляет интересный пример:
Для другого примера
struct X {
mutable int i;
int j;
};
struct Y {
X x;
Y();
};
const Y y;
y.x.i++; // well-formed: mutable member can be modified
y.x.j++; // ill-formed: const-qualified member modified
Y* p = const_cast<Y*>(&y); // cast away const-ness of y
p->x.i = 99; // well-formed: mutable member can be modified
p->x.j = 99; // undefined: modifies a const member
, который указывает, что через const_cast
, можно изменить mutable
членов const
квалифицированного объекта, в то время как вы не можете сделать это с не mutable
членами.
Насколько я понимаю, это из-за оригинала const
из y
самого себя.Что произойдет, если мы избавимся от ключевого слова mutable
, квалификатора const
для y
, но изменим поля в методе const
?
Пример ниже:
#include <vector>
struct foo {
std::vector<int> vec{};
void bar() const {
auto& raw_ref = const_cast<std::vector<int>&>(vec);
raw_ref.push_back(0); // ok?
auto* raw_this = const_cast<foo*>(this);
raw_this->vec.push_back(0); // ok?
}
};
int main() {
foo f{};
f.bar();
}
Имеет ли он неопределенное поведение?Я думаю, что это не так, поскольку мы изменяем изначально не const
, но в контексте const
.
Кроме того, обратите внимание, что я предоставил два способа изменения vec
.Один с не const
ссылкой и один с не const
указателем на this
(который изначально был const
в этом контексте из-за foo::bar
, являющегося const
методом).Отличаются ли они каким-либо особым образом, учитывая контекст вопроса?Я хотел бы предположить, что оба в порядке здесь.
Отказ от ответственности: я знаю ключевое слово mutable
, но этот дизайн (не только ошибочный) является просто примером.Можно предположить, что автор кода хотел запретить все способы изменения vec
, за исключением push_back
s.