2010-03-16 21 views
55

मेरे पास एक कक्षा है जो अनिवार्य रूप से केवल मेरे आवेदन के माध्यम से उपयोग की जाने वाली निरंतर परिभाषाओं का एक गुच्छा रखती है। किसी कारण से हालांकि, long रों संकलन लेकिन float रों नहीं है:स्थिर कॉन्स फ्लोट की अनुमति क्यों नहीं है?

1>c:\projects\myproject\Constant_definitions.h(71) : error C2864: 'MY_CONSTS::FLOAT_CONST' : only static const integral data members can be initialized within a class 

मैं कुछ याद आ रही हूँ:

class MY_CONSTS 
{ 
public : 
    static const long LONG_CONST = 1;  // Compiles 
    static const float FLOAT_CONST = 0.001f; // C2864 
}; 

निम्न त्रुटि देता है?

+3

संभावित डुप्लिकेट [मेरे पास कक्षा में गैर-अभिन्न स्थिरांक सदस्य क्यों नहीं हो सकता है?] (Http://stackoverflow.com/questions/370283/why-cant-i-have-a-non- अभिन्न-स्थैतिक-कॉन्स्ट-सदस्य-इन-ए-क्लास) –

उत्तर

53

वास्तविक सवाल आपसे पूछा जवाब देने के लिए: "मानक इसलिए कहते हैं क्योंकि"।

स्थैतिक, स्थिर, अभिन्न प्रकार (गणना सहित) के केवल चर वर्ग वर्ग घोषणा के अंदर आरंभ किए जा सकते हैं। यदि एक कंपाइलर फ्लोट्स के ऑनलाइन प्रारंभिकरण का समर्थन करता है, तो यह एक विस्तार है। जैसा कि अन्य ने इंगित किया है, स्थैतिक, स्थिर, गैर-अभिन्न चर से निपटने का तरीका कक्षा को संबंधित स्रोत फ़ाइल (शीर्षलेख नहीं) में परिभाषित करना और प्रारंभ करना है।

सी ++ स्टैंडर्ड धारा 9.2 "क्लास सदस्य" आइटम 4:

A member-declarator can contain a constant-initializer only if it declares a static member (9.4) of const integral or const enumeration type, see 9.4.2.

धारा 9.4.2 "स्टैटिक डाटा सदस्य" आइटम 2:

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.

+10

। अच्छा है कि सी ++ 0 एक्स इन-क्लास फ्लोट प्रारंभकर्ताओं का समर्थन करेगा। –

+3

एक और अच्छा तरीका उस मूल्य को वापस करने के लिए एक समारोह बनाना होगा। लाभ यह है कि मान संकलक के लिए दृश्यमान है (जो फ़ंक्शन को रेखांकित कर सकता है)। एक इन-सीपीपी परिभाषा अन्य टीयू के मूल्य का पर्दाफाश नहीं करेगी। –

+1

फ़ंक्शन दृष्टिकोण के लिए एक और लाभ है: आप "स्थिर प्रारंभिक आदेश फ़ियास्को" से बच सकते हैं जो तब हो सकता है जब आप अन्य संकलन इकाइयों से अन्य स्थिर मानों का उपयोग करके स्थिर मानों को प्रारंभ करने का प्रयास करते हैं (हालांकि यह शायद अंतर्निर्मित प्रकारों के साथ नहीं होगा फ्लोट)। –

34

आप उन्हें अपने cpp फ़ाइलों में से एक के शरीर में प्रारंभ करना चाहिए:

class MY_CONSTS 
{ 
public : 
    static const long LONG_CONST = 1;  // Compiles 
    static const float FLOAT_CONST; 
}; 

const float MY_CONSTS::FLOAT_CONST = 0.001f; 
+3

कुछ कंपाइलर्स अभी भी उम्मीद करेंगे कि आप 'LONG_CONST' के लिए स्थान परिभाषित करने के लिए सीपीपी फ़ाइल में एक और पंक्ति प्राप्त करें:' लंबा लंबा MY_CONSTS :: LONG_CONST; 'ध्यान दें कि आप डॉन करते हैं यहां प्रारंभिकरण दोहराएं। –

+3

@ एड्रियन: अंतर यह है कि ये कंपाइलर टूटा हुआ है। – sbi

+1

@ एसबीआई: क्या? एक स्थिर सदस्य की इनलाइन प्रारंभिकरण परिभाषा की आवश्यकता को दूर नहीं करता है। –

3

किस बारे में:

class MY_CONSTS 
{ 
public : 
    static const long LONG_CONST; 
    static const float FLOAT_CONST; 
}; 

const long MY_CONSTS::LONG_CONST = 1; 
const float MY_CONSTS::FLOAT_CONST = 0.001f; 

(हालांकि, मैं नहीं इस विशेष मामले का कोई स्पष्टीकरण नहीं दे सकते हैं ...)

19

Stroustrup's explanation देखें। प्रासंगिक बोली:

A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects. See D&E for an explanation of C++'s design tradeoffs.

+12

यह वास्तव में प्रश्न का उत्तर नहीं देता है। एक 'लंबा' क्यों शुरू किया जा सकता है और 'फ्लोट' नहीं? अनुमानित 'लम्बी' को मेमोरी में [ऑब्जेक्ट] के रूप में संग्रहीत करने की आवश्यकता नहीं है 'लेकिन' फ्लोट 'करता है? उसका क्या अर्थ निकलता है? – KitsuneYMG

+14

लंबे स्थिर को सीपीयू निर्देश का एक हिस्सा बनाया जा सकता है (कम से कम इंटेल CPUs पर)। एक फ्लोट स्मृति में होने में मदद नहीं कर सकता है। नोटेशन के मामूली दुर्व्यवहार का उपयोग करके, आप कह सकते हैं कि लंबे समय तक रेखांकित किया जा सकता है, और फ्लोट नहीं कर सकते हैं। वास्तव में –

3
से

मानक 9.4.2/4

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.

और 5.19/1:

In several places, C + + requires expressions that evaluate to an integral or enumeration constant: as array bounds (8.3.4, 5.3.4), as case expressions (6.4.2), as bit-field lengths (9.6), as enumerator initializers (7.2), as static member initializers (9.4.2), and as integral or enumeration non-type template arguments (14.3). constant-expression: conditional-expression An integral constant-expression can involve only literals (2.13), enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions (8.5), non-type template parameters of integral or enumeration types, and sizeof expressions. Floating literals (2.13.3) can appear only if they are cast to integral or enumeration types. Only type conversions to integral or enumeration types can be used. In particular, except in sizeof expressions, functions, class objects, pointers, or references shall not

8

दूसरों द्वारा दिए गए मानक शब्द के तहत तर्क समान है, जिसके लिए टेम्पलेट तर्क फ़्लोटिंग पॉइंट नंबर नहीं हो सकते हैं। लगातार परिणाम प्राप्त करने के लिए आपको संकलन समय पर किए गए एक ही मूल्यांकन को लागू करने के लिए संकलक की आवश्यकता होगी, और यह क्रॉस-कंपाइलर के लिए जटिल हो सकता है और उस स्थिति में जहां प्रोग्राम राउंडिंग मोड के साथ खेलता है।

स्मृति से, सी ++ 0 एक्स में, निरंतर अभिव्यक्ति की धारणा बढ़ा दी गई है और इसलिए आपका कोड मान्य होगा (लेकिन यह फ्लोटिंग पॉइंट निरंतर अभिव्यक्ति के परिणाम में निर्दिष्ट नहीं है जब रन-टाइम पर मूल्यांकन किया जाता है या संकलन समय पर)।

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