Является ли изменение неизменяемого члена неконстантного объекта в методе const неопределенным поведением? - PullRequest
0 голосов
/ 18 февраля 2019

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.

1 Ответ

0 голосов
/ 18 февраля 2019

В указанном вами абзаце фактически прописано, что именно не определено [dcl.type.cv]

За исключением того, что любой член класса, объявленный как изменяемый, может быть изменен, любая попытка изменитьконстантный объект при его жизни приводит к неопределенному поведению.

Константная ссылка / указатель на неконстантный объект не делает этот объект константным объектом, все ваши обращения к нему корректны.

...