2010-04-20 14 views
5

पर विचार करें निम्नलिखित कोड:पॉइंटर-टू-म्यूटेबल-सदस्य कैसे बनाएं?

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

संकलक एक त्रुटि संदेश उत्पन्न करता है। बात यह है कि सदस्य m उत्परिवर्तनीय है इसलिए इसे m बदलने की अनुमति है। लेकिन समारोह हस्ताक्षर उत्परिवर्ती घोषणा छुपाता है।

इस कोड को संकलित करने के लिए पॉइंटर-टू-म्यूटेबल-सदस्य को कैसे रद्द करें? यदि यह असंभव है तो कृपया मानक सी ++ से लिंक करें।

उत्तर

8

इस कोड को सी ++ मानक 5.5/5 के अनुसार बीमार बनाई है:

सीवी-योग्यता, पर प्रतिबंध और जिस तरह से ऑपरेंड के सीवी-क्वालिफायर निर्माण करने के लिए जोड़ दिया जाता है परिणाम के सीवी-क्वालीफायर , 5.2.5 में दिए गए E1.E2 के लिए नियमों के समान हैं। [नोट: सदस्य को पॉइंटर का उपयोग करना संभव नहीं है जो एक कॉन्स्ट क्लास ऑब्जेक्ट को संशोधित करने के लिए एक परिवर्तनीय सदस्य को संदर्भित करता है। उदाहरण के लिए ,

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 

]

आप इस प्रकार इस समस्या को वैकल्पिक हल के लिए आवरण वर्ग इस्तेमाल कर सकते हैं:

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

लेकिन मुझे लगता है आप अपने कोड नया स्वरूप पर विचार करना चाहिए।

+0

बहुत अच्छा .. वर्कअराउंड सही है! –

संबंधित मुद्दे