How to create pointer-to-mutable-member?
-
28-09-2019 - |
Question
Consider the following code:
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>();
}
};
Compiler generates an error message. The thing is that the member m
is mutable therefore it is allowed to change m
. But the function signature hides mutable declaration.
How to decalre pointer-to-mutable-member to compile this code? If it is impossible please link to Standard C++.
Solution
This code is ill-formed according to C++ Standard 5.5/5:
The restrictions on cv-qualification, and the manner in which the cv-qualifiers of the operands are combined to produce the cv-qualifiers of the result, are the same as the rules for E1.E2 given in 5.2.5. [Note: it is not possible to use a pointer to member that refers to a mutable member to modify a const class object. For example,
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
]
You could use wrapper class to workaround this problem as follows:
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>();
}
};
But I think you should consider redesign your code.