2012-05-16 15 views
12

की तरह एक निरंतर अभिव्यक्ति में प्रकट नहीं कर सकते हैं मेरे पास है कुछ स्थिर स्थिरांक सदस्योंक्यों स्थिर स्थिरांक सदस्यों के स्विच '

class MyClass : public MyBase 
{ 
public: 
    static const unsigned char sInvalid; 
    static const unsigned char sOutside; 
    static const unsigned char sInside; 
    //(41 more ...) 
} 

सीपीपी

const unsigned char MyClass::sInvalid = 0; 
const unsigned char MyClass::sOutside = 1; 
const unsigned char MyClass::sInside = 2; 
//and so on 

के निम्नलिखित घोषणा पर

unsigned char value; 
... 
switch(value) { 
    case MyClass::sInvalid : /*Do some ;*/ break; 
    case MyClass::sOutside : /*Do some ;*/ break; 
    ... 
} 
: कुछ बिंदु मैं की तरह एक स्विच में उन लोगों के मूल्य का उपयोग करना चाहते

लेकिन मैं निम्नलिखित संकलक त्रुटि मिलती है: त्रुटि: 'MyClass :: sInvalid' एक निरंतर अभिव्यक्ति में प्रकट नहीं कर सकते हैं।

मैं अन्य स्विच नहीं कर सकते-दिखाई-निरंतर-सामान पढ़ लिया है और नहीं के बाद से मैं क्यों उन static const unsigned char निरंतर अभिव्यक्ति नहीं कर रहे हैं नहीं मिलता है मेरे लिए एक जवाब मिला।

मैं जीसीसी 4.5 का उपयोग कर रहा हूं।

उत्तर

17

आप देख समस्याओं तथ्य यह है कि इस

static const unsigned char sInvalid; 

एक संकलन समय निरंतर अभिव्यक्ति नहीं किया जा सकता, क्योंकि संकलक अपने मूल्य पता नहीं है की वजह से कर रहे हैं। उन्हें इस तरह के शीर्षलेख में प्रारंभ करें:

class MyClass : public MyBase 
{ 
public: 
    static const unsigned char sInvalid = 0; 
    ... 

और यह काम करेगा।

+0

गलती से -1'd। आपको यह निर्दिष्ट करना चाहिए कि प्रारंभिक ** ** परिभाषा ** कक्षा परिभाषा के अंदर होना चाहिए, केवल हेडर नहीं।यदि आप उन्हें शीर्षलेख में प्रारंभ करते हैं, लेकिन कक्षा के बाहर, आपको लिंक त्रुटियां मिलेंगी। –

+0

@LuchianGrigore: ठीक है, मैंने यह स्पष्ट किया है। वैध समाधान के लिए – jpalecek

+4

+1, लेकिन मुझे अभी भी एक चीज बेहतर है। –

9

मान वास्तव में const हैं, लेकिन वे संकलन-समय स्थिरांक नहीं हैं।

एक switch हालत संकलन समय पर हल हो गई है, रन-टाइम नहीं। आप sInvalid को जो भी मूल्य मान सकते हैं, जब तक कि यह केवल एक बार हो, और switch रन-टाइम तक इसके बारे में कभी नहीं जान पाएगा।

ऐसा लगता है कि आप स्थिरांक के बजाय enum एस का उपयोग करने के बेहतर हैं। इस तथ्य के अलावा कि यह काम करेगा, यह अधिक उचित डिजाइन-वार लगता है।

+0

आपके मूल्यवान स्पष्टीकरण के लिए धन्यवाद! एनम मेरी पहली पसंद थी, लेकिन मैं उन जगहों को काटने वाले तरीके से और अन्य सरणी सामग्री में लगातार उपयोग कर रहा हूं, मुझे वास्तव में उन्हें 'हस्ताक्षर किए गए चार' होने की आवश्यकता है। मुझे स्पष्ट 'हस्ताक्षरित चार' प्रकारों का उपयोग किए बिना इसे ठीक से काम करने का कोई तरीका नहीं मिला। डिफॉल्ट एनम का उपयोग करके इसे हर जगह 'हस्ताक्षरित चार' पर डालें, कोड को इस तरह के समाधान के साथ कैमरे को इतनी अनावश्यक बना दें। – vrince

+0

क्या आप निरंतर और संकलन-समय निरंतर के बीच के अंतर को समझा सकते हैं? (या एक स्पष्टीकरण के लिए लिंक?) – dbliss

2

आप उन्हें संकलन समय स्थिरांक बनाने के लिए enum चाल का उपयोग कर सकते हैं:

class MyClass 
{ 
public: 
    enum { 
     sInvalid, 
     sOutside, 
     sInside, 
     //(41 more ...) 
    }; 
}; 

अपने कोड में, आप अभी भी अहस्ताक्षरित चार को assing, कुछ इस तरह के enum का उपयोग कर सकते हैं:

int main(int argc, char *argv[]) 
{ 
    unsigned char buf[32]; 
    buf[0] = MyClass::sInvalid; //int to unsigned char 
    return buf[0]; //Cast back to int (and avoid a warning a -Wall) 
} 

और अपने स्विथ स्टेटमेंट में MyClass::sInvalid का उपयोग करें।

+0

हाँ, मुझे वास्तव में उन्हें 'हस्ताक्षरित चार' होने की आवश्यकता है और मैं उन सभी कंपाइलर संस्करणों के साथ 'एनम माईएनम: अप्रमाणित चार' काम करने में सक्षम नहीं था। – vrince

+0

स्विच दिमाग में नहीं होगा। मेरा संपादन देखें, g ++ 4.6.1 -Wall के साथ संकलित करें – ixe013