2010-04-29 17 views
27

मैं कक्षा के अंदर एक निश्चित रूप से परिभाषित करना चाहता हूं जो अधिकतम संभव int है। कुछ इस तरह:निरंतर अभिव्यक्तियों में numeric_limits :: max() का उपयोग

class A 
{ 
    ... 
    static const int ERROR_VALUE = std::numeric_limits<int>::max(); 
    ... 
} 

इस घोषणा निम्न संदेश के साथ संकलित करने के लिए विफल रहता है:

numeric.cpp:8: error: 'std::numeric_limits::max()' cannot appear in a constant-expression numeric.cpp:8: error: a function call cannot appear in a constant-expression

मुझे समझ में क्यों यह काम नहीं करता है, लेकिन दो बातें मुझे अजीब लग रही है:

  1. मुझे लगातार अभिव्यक्तियों में मूल्य का उपयोग करने का एक प्राकृतिक निर्णय लगता है। भाषा डिजाइनर ने अधिकतम() एक फ़ंक्शन को इस उपयोग की अनुमति क्यों नहीं देनी है?

  2. में कल्पना का दावा 18.2.1 कि

    For all members declared static const in the numeric_limits template, specializations shall define these values in such a way that they are usable as integral constant expressions.

    इसका मतलब यह नहीं है कि मैं और मेरी स्थिति में इसका इस्तेमाल करने में सक्षम होना चाहिए यह त्रुटि संदेश का खंडन नहीं करता है?

धन्यवाद।

+1

आप climits उपयोग कर सकते हैं http://www.cplusplus.com/reference/clibrary/climits/ – Anycorn

+1

@aaa: लेकिन 'climits' टेम्पलेट्स के साथ अच्छा नहीं खेलेंगे। दुर्भाग्य से – UncleBens

+2

@Uncle। सिद्धांत रूप में टेम्पलेट्स में परिभाषित कर सकते हैं, कुछ काम लेकिन करने योग्य। या integer_traits को बढ़ावा दें मुझे लगता है कि उन्हें पहले से ही प्रदान किया गया है: 'integer_traits <> :: const_max/const_min' – Anycorn

उत्तर

16

जबकि मौजूदा मानक में समर्थन का अभाव है, अभिन्न प्रकार Boost.IntegerTraits के लिए आपको संकलन समय स्थिरांक const_min और const_max देता है।

समस्या §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 name- space scope if it is used in the program and the namespace scope definition shall not contain an initializer.

दूसरों को पहले से ही उल्लेख किया है numeric_limit रों min() और max() बस अभिन्न निरंतर भाव नहीं हैं, अर्थात संकलन समय स्थिरांक।

13

आप चाहते हैं:

#include <limits> 

struct A { 
static const int ERROR_VALUE; 
}; 

const int A::ERROR_VALUE = std::numeric_limits<int>::max(); 

एक .cpp फ़ाइल में एक शीर्षक में वर्ग/struct और परिभाषा रखो।

+2

उपरोक्त परिभाषित ERR_VALUE टेम्पलेट तर्क के रूप में उपयोग किया जा सकता है? – Anycorn

+2

कक्षा और बाहर के अंदर प्रारंभिकता के बीच क्या अंतर है? मुझे पता है कि मैं कक्षा के अंदर अभिन्न मूल्यों के साथ consts प्रारंभ कर सकते हैं। इसके अलावा, मेरे पास इस तरह के वर्ग का कम से कम एक उदाहरण होना चाहिए, है ना? अन्यथा संकलक इसे शुरू करने का फैसला नहीं कर सकता है? – FireAphis

+0

टैगिंग के साथ: क्या यहां कोई लाइब्रेरी नहीं है (शायद बूस्ट) जो उन मानों को फिर से परिभाषित करती है ताकि उन्हें मेटामैटप्लेट प्रोग्रामिंग में उपयोग किया जा सके? संकलन-समय पर उन्हें हमारे निपटारे में समझना होगा ... –

15

एक दोष का एक सा तरह लग रहा है ...

C++ 0x में, numeric_limits, सब कुछ constexpr के साथ चिह्नित करना होगा जिसका अर्थ है आप संकलन समय स्थिरांक के रूप में min() और max() उपयोग करने के लिए सक्षम हो जाएगा।

+0

उन लोगों के लिए, स्पष्ट रूप से इसका समर्थन विजुअल स्टूडियो 2015 में जोड़ा गया था। अब अगर मैं 2013 से आईटी अपडेट कर सकता हूं ... – Phlucious

4

यह विरोधाभास नहीं करता है, क्योंकि max को static const परिभाषित नहीं किया गया है। यह सिर्फ एक स्थिर सदस्य समारोह है। कार्य कॉन्स्ट नहीं हो सकते हैं, और स्थैतिक सदस्य फ़ंक्शंस को किसी भी दाहिने ओर एक कॉन्स संलग्न नहीं किया जा सकता है।

सीमा के दोहरे संस्करण में double max() भी है, और सी ++ 03 में यह static double const max = ... कहने के लिए काम नहीं करेगा। तो सुसंगत होने के लिए, max() सीमा टेम्पलेट के सभी संस्करणों के लिए एक फ़ंक्शन है।

अब, यह ज्ञात है कि max() ऐसा उपयोग करने में सक्षम नहीं है, और सी ++ 0x पहले से ही इसे constexpr फ़ंक्शन बनाकर हल करता है, जिससे आपके प्रस्तावित उपयोग की अनुमति मिलती है।

2
  • मैं के रूप में मैं अपने प्रश्न से समझा आप के रूप में ज्यादा के जवाब देने की कोशिश करेंगे:

1- यदि आप चाहते हैं अपने कार्यक्रम में एक स्थिर स्थिरांक पूर्णांक एक समारोह के साथ प्रारंभ करने के लिए:

int Data() 
{ 
return rand(); 
} 

class A 
{ 
public : 
    static const int ee; 
}; 
const int A::ee=Data(); 

यह वी.एस. 2008

2- पर काम करता है आप, किसी दिए गए डेटा प्रकार के लिए अधिकतम और न्यूनतम संख्या प्राप्त करने के तो इन परिभाषाओं INT_MAX, में उपयोग करना चाहते हैं T_MIN, LONG_MAX और इतने पर ..

3- यदि आप इनमें से wrt टेम्पलेट प्रकार, तो कठिन कोड टेम्पलेट्स खुद

template<> 
int MaxData() 
{ 
return INT_MAX; 
} 

और

template<> 
long MaxData() 
{ 
return LONG_MAX ; 
} 

और उन्हें फोन उपयोग करने की आवश्यकता है लेकिन इस तरह

int y=MaxData<int>(); 

4- और यदि आप केवल बाइनरी का प्रतिनिधित्व कर रहे हैं केवल प्रकार है, तो इस का उपयोग करें:

template <class T> 
T MaxData(){ 
    return ~(1<<((sizeof(T)*8)-1)); 
} 

और इस

template <class T> 
T MinData(){ 
    return (1<<((sizeof(T)*8)-1)); 
} 

आशा इस मदद कर सकता है ..

+0

संख्यात्मक मान 8 के बजाय, क्लाइमिट्स (सीमा.h) से CHAR_BIT मैक्रो का उपयोग करें। – Aconcagua

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