Рассмотрите следующий код:
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
. Но функциональная подпись скрывает изменяемое объявление.
Как объявить, что pointer-to-mutable-member компилирует этот код? Если это невозможно, свяжите со Стандартом C++.
Этот код неверно сформирован в соответствии со Стандартом C ++ 5.5 / 5:
Ограничения на cv-квалификацию, и способ, которым используются cv-квалификаторы операндов , объединенные для получения cv-квалификаторов результата, аналогичны правилам для E1.E2, приведенным в 5.2.5. [Примечание: невозможно использовать указатель на член, который ссылается на изменяемый член , для изменения объекта константного класса . Например,
struct S { mutable int i; }; const S cs; int S: : * pm = & S :: i; // pm относится к изменяемому члену S :: i cs. * pm = 88; // неправильно сформированный: cs - это константный объект
]
Вы можете использовать класс-оболочку для решения этой проблемы следующим образом:
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>();
}
};
Но я думаю, вам следует подумать о переделке вашего кода.