2010-04-20 23 views
5

Aşağıdaki kodu düşünün:İşaretçi-dönüştürülebilir üye nasıl oluşturulur?

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

Derleyici bir hata mesajı oluşturur. Buradaki şey, m üyesinin değişebilir olmasıdır, bu nedenle m'u değiştirmesine izin verilir. Ancak işlev imzası değişebilir bildirimi gizler.

Bu kodu derlemek için işaretçiden dönüştürülebilen üye nasıl ayrılır? İmkansızsa, lütfen Standart C++ 'ya bağlanın.

Bu kod, 5.5/5 ° C++ standart göre kötü oluşturulur

cevap

8

:

ev yeterlilik, kısıtlamalar ve işlenen ev-eleme üretmek için birleştirildiği şekilde sonucun cv-niteleyicileri , 5.2.5'de verilen E1.E2 için kuralları ile aynıdır. [Not: , const sınıfı nesnesini değiştirmek için bir değişken üyesine başvuran üye için bir işaretçi kullanmak mümkün değildir.

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

Ama kodunuzu yeniden tasarlamak düşünmelisiniz düşünüyorum: Bunu şöyle sorunu geçmenin sarmalayıcı sınıf kullanabilirsiniz Örneğin ,

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 

]

.

+0

Çok iyi .. Çözüm mükemmel! –