2012-06-18 7 views
8

मैं टेम्पलेट क्लास विधि के अंदर निरंतर संख्यात्मक अक्षर रखने का समाधान ढूंढने का प्रयास कर रहा हूं। मैं फ्लोट या डबल प्रकारों के साथ उपयोग करने के लिए कुछ गणित टेम्पलेट कक्षाएं बना रहा हूं। समस्या यह है कि डेटा प्रकार के आधार पर अक्षर अलग-अलग होते हैं (उदाहरण के लिए फ्लोट के लिए "0.5 एफ" और डबल के लिए "0.5")। अब तक, मैं दो समाधान के साथ आया हूँ। पहले एक के लिए कुछ काल्पनिक कोड:फ्लोट और डबल लिटरल के लिए टेम्पलेट क्लास में फ़ंक्शन विशेषज्ञता

template <typename T> 
class SomeClass 
{ 
    public: 
     T doSomething(T x); 
}; 

template <> 
float SomeClass<float>::doSomething(float x) 
{ 
    float y = 0.5f; 
    /* 
    * Do computations... 
    */ 
    return x; 
} 

template <> 
double SomeClass<double>::doSomething(double x) 
{ 
    double y = 0.5; 
    /* 
    * Do computations... 
    */ 
    return x; 
} 

हर प्रकार इसके साथ प्रयोग किया जाता है के लिए पूरी तरीकों को फिर से लिखने बलों ऊपर दृष्टिकोण।

एक और दृष्टिकोण:

template <typename T> 
class SomeClass 
{ 
    public: 
     T doSomething(T x); 

    private: 
     T getValue(); 
}; 

template <typename T> 
T SomeClass<T>::doSomething(T x) 
{ 
    T y = getValue(); 
    /* 
    * Do computations... 
    */ 
    return x; 
} 

template <> 
float SomeClass<float>::getValue() 
{ 
    return 0.5f; 
} 

template <> 
double SomeClass<double>::getValue() 
{ 
    return 0.5; 
} 

यह एक ही तरीके का विशिष्ट प्रकार के लिए कई बार लिखने के लिए की आवश्यकता नहीं है, लेकिन एक बहुत getValue() हर "जादुई संख्या" होने की जरूरत है कि के लिए तरीकों करने की आवश्यकता है विधि के अंदर प्रयोग किया जाता है।

क्या यह हल करने के लिए कोई और "अधिक सुरुचिपूर्ण" तरीका है?

+1

अपने ही बारे में शाब्दिक हैं, तो मुझे लगता है कि आप कास्टिंग static_cast () – Mohammad

+0

मैं इसे अपने प्रश्न में उल्लेख नहीं था, उपयोग कर सकते हैं, लेकिन मैं किसी भी रूपांतरण, न तो स्पष्ट है और न ही निहित से बचने के लिए चाहते हैं। – umebe

उत्तर

0

आपको इसके बारे में चिंता करने की आवश्यकता नहीं है - 0.5 का उपयोग करें और यदि प्रकार तैरता है तो कंपाइलर अभी भी उसी मूल्य पर बेहतर रूप से प्रारंभ करेगा जैसे कि आप 0.5 एफ का उपयोग करेंगे।

यह थोड़ा घना है, लेकिन आप मेरा उत्तर का हिस्सा यहाँ "अन्य बहुरूपता समर्थन तंत्र" के माध्यम से पढ़ने के लिए चाहते हो सकता है: Polymorphism in c++

समारोह के दौरान नाव निरंतर के और अधिक सामान्य उपयोग के लिए - विशेष रूप से में तुलना और भाव - इसे पढ़ने के लिंक bluemess नीचे उल्लेख के लायक है ....

+0

मान लें कि मैं "0.5" अक्षर का उपयोग करूंगा। क्या इससे कुछ बिंदु पर फ़्लोट करने के लिए अंतर्निहित (रनटाइम?) रूपांतरण नहीं होगा? उदाहरण में मैंने दिया कि यह महत्वपूर्ण नहीं हो सकता है, लेकिन आम तौर पर मैं रूपांतरणों से बचूंगा। – umebe

+1

यह संकलन-समय रूपांतरण होगा। –

+0

मुझे पता चला है कि कुछ मामलों में फ्लोट के लिए "0.5" शाब्दिक का उपयोग करके कई रूपांतरणों का कारण बन जाएगा जो कि यहां समझाया गया है: [क्या हम आम तौर पर सरल डबल अक्षरों की बजाय फ्लोट के लिए फ्लोट अक्षर का उपयोग करते हैं?] (Http://stackoverflow.com/ए/7662804/1464168) – umebe

0

मान लिया जाये कि यह दो विशेषज्ञताओं में विभिन्न मूल्यों के उपयोग करने के लिए (यह, 0.5 और 0.5f के लिए आवश्यक नहीं है उदाहरण के लिए) यह एक बहुत होगा वास्तव में आवश्यक है करने के लिए कम टाइपिंग:

template <typename T> 
class SomeClass 
{ 
    public: 
    T doSomething(T x); 

    private: 
    static const T magic_number_1; 
}; 

template <typename T> 
T SomeClass<T>::doSomething(T x) 
{ 
    T y = magic_number_1; 
    /* 
    * Do computations... 
    */ 
    return x; 
} 

template <> 
const float SomeClass<float>::magic_number_1 = 0.5f; 

template <> 
const double SomeClass<double>::magic_number_1 = 0.5; 
+0

ठीक है, यह बेहतर लगता है कि अलग getValue() विधियों। – umebe

1

आपके उत्तरों और टिप्पणियों के लिए सभी को धन्यवाद। मैंने खुद को अब तक जो कहा गया है उसका सारांश बनाने और मेरे निष्कर्ष जोड़ने की अनुमति दी।

मैं फ्लोट या डबल प्रकार के साथ उपयोग करने के लिए तत्काल होने के लिए कुछ गणित वर्ग टेम्पलेट को लागू करने जा रहा हूं। कक्षा में आंतरिक रूप से कुछ संख्यात्मक अक्षर का उपयोग करने की आवश्यकता है। वे कुछ सामान्य रूप से इस्तेमाल किए गए संख्यात्मक अक्षर और स्थिरांक होंगे, जैसे 0.0, 0.5, 1.0, पीआई आदि। मैं अपने प्रकार के आधार पर अलग-अलग अक्षरों पर कक्षा तत्काल कार्य करने का समाधान ढूंढ रहा हूं।

फ्लोट और डबल अक्षर का उपयोग या नहीं?

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

float foo(float x) 
{ 
    return x * 3.14; 
} 

यह दोगुना संगणना, फिर परिणाम वापस परिवर्तित फ्लोट करने के लिए एक्स कन्वर्ट करने के लिए संकलक बाध्य करेगा। पेशेवरों और इस तरह के व्यवहार की विपक्ष:

सकारात्मक:

  • प्रेसिजन लाभ वास्तविक संगणना डबल परिशुद्धता में किया जाएगा क्योंकि।

विपक्ष:

  • यदि प्रदर्शन एक मुद्दा है, यह तेजी से और साथ ही धीमी निष्पादन में परिणाम हो सकता है, पर्यावरण और मंच पर निर्भर करता है। यह कार्यान्वयन के आधार पर कुछ प्रदर्शन परिवर्तन प्रस्तुत करता है, जो है जहां तक ​​मुझे बुरा माना जाता है।
  • कंप्यूटेशंस असंगतता का परिचय देता है क्योंकि कुछ ऑपरेशन फ्लोट पर किए गए हैं और कुछ युगल पर, शाब्दिक उपयोग के आधार पर होंगे। यह कुछ बग एक्सपोजर भी खोल सकता है।
  • यह पहली जगह में फ्लोट के लिए कक्षा को विशेषज्ञता देने का विचार तोड़ता है क्योंकि आंतरिक रूप से गणना डबल्स पर भी की जाएगी।

निष्कर्ष में, लक्ष्य किसी भी अतिरिक्त रूपांतरण के बिना उचित प्रकार पर कक्षा तत्काल कार्य करना है। हर जगह डबल टाइप अक्षर का उपयोग करने का विचार, जैसे कि 0.5 और संकलक को उचित रूपांतरण संभालना छोड़ना एक विकल्प नहीं है।

विषय पर अधिक: Should we generally use float literals for floats instead of the simpler double literals?

संभावित समाधान? हर टेम्पलेट इन्स्टेन्शियशन प्रकार शाब्दिक है जहां के लिए

  • विशेषज्ञ तरीकों का इस्तेमाल किया जा सकता है। यह शायद सबसे खराब समाधान है क्योंकि यह अक्षरों में मामूली परिवर्तनों के साथ दो बार एक ही कोड लिखने के लिए मजबूर करता है।
  • विशेष getValue<type>() विधियां, या Jonathan Wakely posted - विशेष सदस्यों को बनाएं। इससे getZeroPointFive<float>() जैसे वर्ग में कुछ मूर्ख नामित सदस्य या विधियां हो सकती हैं।
  • मोहम्मद और टोनी डेल्रॉय ने इंगित किया कि static_cast<T>() के साथ हर शाब्दिक लपेटकर चाल चल जाएगी। उचित प्रकार में रूपांतरण संकलन समय पर किया जाएगा।
+0

एक बेहतर समाधान आया है ... मोहम्मद से टिप्पणी ... अभिव्यक्तियों में भाग लेने से पहले मानों को कास्ट करना ala static_cast (5.0)।मुझे पता है कि आपको यह पसंद नहीं है, लेकिन यह संकलन समय होने जा रहा है और संख्या के साथ स्थानीयकृत है, जबकि getZeroPointFive आदि नहीं है। –

+0

इसे इंगित करने के लिए धन्यवाद। मैंने इसे संभावित समाधान में जोड़ा है – umebe

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