Как создать указатель на изменяемый член?
Рассмотрим следующий код:
struct Foo
{
mutable int m;
template<int Foo::* member>
void change_member() const {
this->*member = 12; // Error: you cannot assign to a variable that is const
}
void g() const {
change_member<&Foo::m>();
}
};
Компилятор генерирует сообщение об ошибке. Дело в том, что член m
изменчиво, поэтому разрешено изменять m
, Но подпись функции скрывает изменяемое объявление.
Как декалировать указатель на изменяемый член для компиляции этого кода? Если это невозможно, пожалуйста, ссылку на стандарт C++.
1 ответ
Этот код некорректен в соответствии со стандартом C++ 5.5/5:
Ограничения на cv-квалификацию и способ объединения cv-квалификаторов операндов для получения cv-квалификаторов результата аналогичны правилам для E1.E2, приведенным в 5.2.5. [Примечание: невозможно использовать указатель на член, который ссылается на изменяемый член, для изменения объекта класса const. Например,
struct S { mutable int i; }; const S cs; int S::* pm = &S::i; // pm refers to mutable member S::i cs.*pm = 88; // ill-formed: cs is a const object
]
Вы можете использовать класс-оболочку для решения этой проблемы следующим образом:
template<typename T> struct mutable_wrapper { mutable T value; };
struct Foo
{
mutable_wrapper<int> m;
template<mutable_wrapper<int> Foo::* member>
void change_member() const {
(this->*member).value = 12; // no error
}
void g() const {
change_member<&Foo::m>();
}
};
Но я думаю, вам стоит подумать о редизайне своего кода.