2010-04-20 6 views
5

Si consideri il seguente codice:Come creare un membro puntatore-mutabile?

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

compilatore genera un messaggio di errore. Il fatto è che il membro m è modificabile, quindi è consentito modificare m. Ma la firma della funzione nasconde la dichiarazione mutabile.

Come decalificare il puntatore al membro mutabile per compilare questo codice? Se è impossibile, collegarsi a Standard C++.

risposta

8

Questo codice è mal formata secondo C++ standard 5.5/5:

Le restrizioni cv-qualificazione, e il modo in cui i CV-qualificazioni degli operandi sono combinati per produrre i qualificatori di cv del risultato sono uguali alle regole per E1.E2 fornite in 5.2.5. [Nota: non è possibile utilizzare un puntatore al membro che fa riferimento a un membro mutabile per modificare un oggetto di classe const . Per esempio,

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 

]

Si potrebbe utilizzare classe wrapper per risolvere questo problema come segue:

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

Ma penso che si dovrebbe prendere in considerazione ridisegnare il vostro codice.

+0

Molto buono .. La soluzione è perfetta! –