2010-04-20 24 views
5

considere el siguiente código:¿Cómo crear un puntero a miembro mutable?

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>(); 
    } 
}; 

compilador genera un mensaje de error. El caso es que el miembro m es mutable, por lo tanto, está permitido cambiar m. Pero la función de la firma oculta la declaración mutable.

¿Cómo decalre puntero-a-mutable-miembro para compilar este código? Si es imposible, conéctese a la norma C++.

Respuesta

8

Este código está mal formada de acuerdo con C++ estándar 5,5/5:

Las restricciones sobre cv-calificación, y la manera en que los CV-calificadores de los operandos se combinan para producir los cv-calificadores del resultado, son los mismos que las reglas para E1.E2 indicadas en 5.2.5. [Nota: no es posible usar un puntero al miembro que hace referencia a un miembro mutable para modificar un objeto const class . Por ejemplo,

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 

]

Usted podría utilizar clase contenedora para solucionar este problema de la siguiente manera:

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>(); 
    } 
}; 

Pero creo que usted debe considerar el rediseño de su código.

+0

Muy bien ... ¡La solución es perfecta! –

Cuestiones relacionadas