views:

103

answers:

1

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++.

+9  A: 

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.

Kirill V. Lyadvinsky
Very good.. Workaround is perfect!
Alexey Malistov