2011-04-01 16 views
14

मैं लिंकर त्रुटि से विस्मित कर रहा हूँ जब निम्न कोड का उपयोग कर का कारण बनता है:"स्थिर स्थिरांक पूर्णांक" त्रुटि जोड़ने (अपरिभाषित-संदर्भ)

// static_const.cpp -- complete code 
#include <vector> 

struct Elem { 
    static const int value = 0; 
}; 

int main(int argc, char *argv[]) { 
    std::vector<Elem> v(1); 
    std::vector<Elem>::iterator it; 

    it = v.begin(); 
    return it->value; 
} 

बहरहाल, यह विफल रहता है जब जोड़ने - किसी भी तरह यह एक की जरूरत है स्थैतिक आधार "मूल्य" के लिए प्रतीक।

$ g++ static_const.cpp 
/tmp/ccZTyfe7.o: In function `main': 
static_const.cpp:(.text+0x8e): undefined reference to `Elem::value' 
collect2: ld returned 1 exit status 

BTW, यह -O1 या बेहतर के साथ ठीक संकलित; लेकिन यह अभी भी अधिक जटिल मामलों के लिए विफल रहता है। मैं जीसीसी संस्करण 4.4.4 20100726 (Red Hat 4.4.4-13) का उपयोग कर रहा हूं।

कोई भी विचार मेरे कोड के साथ क्या गलत हो सकता है?

+1

[संरचना/वर्ग के अंदर स्थिर स्थिरांक के अजीब अपरिभाषित प्रतीक] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/4891067/weird-undefined-symbols-of-static-constants-inside-a-struct- कक्षा) – karlphillip

+0

उपयोगी लिंक के लिए धन्यवाद! यह एक वैकल्पिक समाधान भी दिखाता है, 'स्ट्रक्चर एलेम {enum {value = 0}; } ', जो बहुत आकर्षक लगता है। – hrr

+0

[सी ++ के संभावित डुप्लिकेट - वर्ग परिभाषा में स्थिर कॉन्स पूर्णांक सदस्यों को परिभाषित करना] (http://stackoverflow.com/questions/3025997/c-defining-static-const-integer-members-in-class-definition) – ks1322

उत्तर

8

आप struct अंदर प्रारंभ करना चाहते हैं, तो आप यह भी कर सकते हैं:

struct Elem { 
    static const int value = 0; 
}; 

const int Elem::value; 
+0

यह है ठंडा! यह काम करता हैं। यदि आप कर सकते हैं (उस बिंदु पर मूल्य जानते हैं) तो इसे संरचना (कक्षा) में प्रारंभ नहीं करना समझ में आता है क्योंकि अन्यथा सभी संभावित अनुकूलन खो जाएंगे। (यानी कुछ स्मृति पते से 0 लोड करने के बजाय सीधे 0 गुजरना।) –

+0

यदि यह वास्तव में स्थिर है, तो "enum hack" का विकल्प है, देखें: http://stackoverflow.com/questions/4891067/weird-undefined -सिम्बोल्स-ऑफ-स्टेटिक-कॉन्स्टेंट-अंदर-ए-स्ट्रक्चर-क्लास समस्याओं को भी वर्णित किया गया है: सी ++ 11 एनम्स के पहले 'int' जैसे 'int' की तरह कोई सभ्य "प्रकार" नहीं है, इसलिए std :: min, std :: make_pair आदि उनके टेम्पलेट तर्क का अनुमान नहीं लगाएंगे ... –

5

struct Elem { 
    static const int value; 
}; 

const int Elem::value = 0; 

etc 

के रूप में यह लिखने की कोशिश करें।

+0

यह दुर्भाग्य से काम नहीं करेगा, जब मान स्विच स्टेटमेंट में एक लेबल है। – Petr

+0

@ पीटर क्षमा करें, सुनिश्चित नहीं है कि आपको वहां क्या कहना है। मैंने कुछ वर्षों में सी ++ का उपयोग नहीं किया है, इसलिए मुझे नहीं पता कि यह 'स्थिर कॉन्स' या क्या है। – jonsca

+1

मुझे खुद को और स्पष्ट करना चाहिए था। मैंने आपको जवाब देने वाले किसी को भी इंगित करने की कोशिश की, कि - हालांकि पूरी तरह से सही - ऐसे मामले हैं जब यह काम नहीं करेगा। उदाहरण के लिए, यदि आप 'वैल्यू' को स्विच में लेबल के रूप में उपयोग करना चाहते हैं, जैसे 'स्विच (एक्स) {केस वैल्यू: ब्रेक; } ' – Petr

2

static वर्ग सदस्यों को आमतौर पर एक संकलन इकाई में कक्षा (घोषित अंदर, परिभाषित) के बाहर परिभाषित किया जाना चाहिए।

मुझे याद नहीं है कि यह const स्थैतिक अभिन्न सदस्यों के इनलाइन प्रारंभिकरण के साथ कैसे इंटरैक्ट करता है।

+1

देखें http://stackoverflow.com/questions/1312241/using-a-static-const-int-in-a-struct-class/1312267#1312267 –

+1

इस मामले के लिए कोई विशेष नियम नहीं है जहां घोषणा की गई है प्रारंभकर्ता --- मानक के अनुसार, घोषित वस्तु को कहीं भी परिभाषित किया जाना चाहिए यदि इसका संभावित रूप से उपयोग किया जाता है। व्यावहारिक रूप से, अधिकांश कंपाइलर इस संबंध में दोषपूर्ण होते हैं, और परिभाषा गुम होने पर, कुछ उपयोगों के लिए केवल एक त्रुटि उत्पन्न करेंगे, न कि दूसरों के लिए। (कौन से उपयोग कभी निर्दिष्ट नहीं होते हैं, और आमतौर पर अनुकूलन स्तर के आधार पर भिन्न होते हैं।) –

1

ऐसा क्यों न करें?

return Elem::value; 

लेकिन उत्तर यह है कि आप घोषणा में मूल्य निर्दिष्ट कर रहे हैं। यह int जैसे मूल प्रकारों के लिए काम करना चाहिए, और केवल जटिल प्रकारों (यानी कक्षाओं के लिए आवश्यक है, जैसे कि यदि आपके पास int की बजाय स्ट्रिंग थी)। अभ्यास में जो मैंने पाया है वह यह है कि आप किस कंपाइलर का उपयोग कर रहे हैं उसके संस्करण के आधार पर यह हिट या मिस है। और, जैसा कि आपने पाया, कौन सा अनुकूलन स्तर।

+0

हालांकि प्रारंभिक समस्या हल नहीं होती है। इसके अलावा, हिट या मिस अक्सर अनिर्धारित व्यवहार का मतलब है। – jonsca

+4

वह जो सवाल पूछ रहा है उससे बचें। –

+0

असल में मैंने इसका उत्तर दिया। मैंने कहा कि वह जो कर रहा है वह काम करना चाहिए (यानी कुछ भी गलत नहीं है), लेकिन व्यवहार में हमेशा काम नहीं करता है। ऐसा लगता है कि उनमें से एक "काम नहीं करता" मामलों में से एक पाया है। –

2

यह भी देखें this post: अनिवार्य रूप से, समस्या यह है कि किसी भी तरह कंपाइलर आपके कोड को Elem :: value का पता लेने में विस्तारित करता है।

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

  • कोई संबंधित समस्या नहीं^_^