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++.
Mutable data members are those members whose values can be changed in runtime even if the object is of constant type. It is just opposite to constant. Sometimes logic required to use only one or two data member as a variable and another one as a constant to handle the data.
The keyword mutable is mainly used to allow a particular data member of const object to be modified. When we declare a function as const, the this pointer passed to function becomes const. Adding mutable to a variable allows a const pointer to change members.
The C++ Standard does not specify whether the iterator of a set container (type set<T>:: iterator) is a mutable or immutable iterator. As a result, popular compilers and their Standard libraries provide different implementations of the set iterator.
The mutable storage class specifier is used only on a class data member to make it modifiable even though the member is part of an object declared as const . You cannot use the mutable specifier with names declared as static or const , or reference members.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With