मुझे लगता है कि अन्य उत्तरों वैकल्पिक दृष्टिकोण को अच्छी तरह से कवर करते हैं, लेकिन कोई भी समझाया नहीं गया है कि enum
(या static const int
) आवश्यक है।
#include <iostream>
int Factorial(int n)
{
if (n == 0)
return 1;
else
return n * Factorial(n-1);
}
int main()
{
std::cout << Factorial(5) << std::endl;
std::cout << Factorial(10) << std::endl;
}
आप इसे आसानी से समझ में सक्षम होना चाहिए:
पहले, निम्न गैर टेम्पलेट बराबर पर विचार करें। हालांकि, यह नुकसान यह है कि फैक्टोरियल का मूल्य रन-टाइम पर गणना की जाएगी, यानी आपके प्रोग्राम को चलाने के बाद कंपाइलर रिकर्सिव फ़ंक्शन कॉल और गणना निष्पादित करेगा।
टेम्पलेट दृष्टिकोण का विचार संकलन-समय पर समान गणना करना है, और परिणामी निष्पादन योग्य में परिणाम डालना है। दूसरे शब्दों में, उदाहरण आप समान रूप से कुछ ले कर जाता है प्रस्तुत:
int main()
{
std::cout << 120 << std::endl;
std::cout << 3628800 << std::endl;
}
लेकिन आदेश है कि प्राप्त करने के लिए, आप 'चाल' संगणना प्रदर्शन में संकलक करने के लिए है। और ऐसा करने के लिए, आपको इसे कहीं भी परिणाम स्टोर करने की आवश्यकता है।
enum
वास्तव में ऐसा करने के लिए में है। मैं यह समझाने की कोशिश करूंगा कि पर काम नहीं करेगा।
यदि आपने नियमित int
का उपयोग करने का प्रयास किया है, तो यह काम नहीं करेगा क्योंकि int
जैसे गैर-स्थिर सदस्य केवल तत्काल वस्तु में सार्थक हैं। और आप इसे इस तरह के मान को असाइन नहीं कर सकते हैं बल्कि इसके बजाय एक निर्माता में ऐसा करते हैं। एक सादा int
काम नहीं करेगा।
आप कुछ है कि बजाय एक uninstantiated वर्ग पर सुलभ हो जाएगा की जरूरत है। आप static int
आज़मा सकते हैं लेकिन यह अभी भी काम नहीं करता है।आप वास्तव में उन परिभाषाओं डालें, तो बाहर के लाइन, कोड संकलन है, लेकिन यह दो 0
रों में परिणाम होगा
c.cxx:6:14: error: non-const static data member must be initialized out of line
static int value=n*Factorial<n-1>::value ;
^ ~~~~~~~~~~~~~~~~~~~~~~~
: clang
आप समस्या का एक बहुत सरल विवरण देना होगा। ऐसा इसलिए है क्योंकि यह फ़ॉर्म प्रोग्राम की शुरुआत के लिए मानों की गणना में देरी करता है, और यह सही क्रम की गारंटी नहीं देता है। यह संभावना है कि गणना के पहले Factorial<n-1>::value
एस प्राप्त किया गया था, और इस प्रकार 0
वापस कर दिया गया था। इसके अतिरिक्त, यह अभी भी हम वास्तव में नहीं चाहते हैं।
अंत में, यदि आप वहां static const int
डालते हैं, तो यह अपेक्षा के अनुसार काम करेगा। ऐसा इसलिए है क्योंकि संकलन समय पर static const
की गणना की जानी चाहिए, और यह वही है जो हम चाहते हैं। फिर से कोड टाइप करते हैं:
#include <iostream>
template <unsigned n>
struct Factorial
{
static const int value=n*Factorial<n-1>::value ;
};
template <>
struct Factorial<0>
{
static const int value=1;
};
int main()
{
std::cout << Factorial<5>::value << std::endl;
std::cout << Factorial<10>::value << std::endl;
}
सबसे पहले आप का दृष्टांत Factorial<5>
; static const int
मजबूर करता है कि कंपाइलर को कंपाइलर समय पर इसकी मान गणना करनी होगी। प्रभावी रूप से, यह Factorial<4>
प्रकार को तत्काल करता है जब इसे किसी अन्य मान की गणना करना पड़ता है। और यह तब तक जाता है जब तक यह Factorial<0>
हिट नहीं करता है जहां मूल्य को तत्काल तत्काल बिना गणना की जा सकती है।
तो, यह वैकल्पिक तरीका और स्पष्टीकरण था। मुझे आशा है कि कोड को समझने में कम से कम थोड़ा सा मददगार होगा।
आप शुरुआत में पोस्ट किए गए रिकर्सिव फ़ंक्शन के प्रतिस्थापन के रूप में उस तरह के टेम्पलेट्स के बारे में सोच सकते हैं। तुम बस की जगह:
static const int value = ...
साथ return x;
,
t<x-1>::value
साथ f(x-1)
,
- और
if (n == 0)
विशेषज्ञता struct Factorial<0>
साथ।
और enum
खुद के लिए, किया गया था के रूप में यह पहले ही बताया है, यह उदाहरण में इस्तेमाल किया गया था static const int
रूप में एक ही व्यवहार लागू करने के लिए। ऐसा इसलिए है क्योंकि सभी enum
मान संकलन-समय पर ज्ञात होने की आवश्यकता है, इसलिए प्रभावी रूप से प्रत्येक अनुरोधित मान को संकलन-समय पर गणना की जानी चाहिए।
यह वास्तव में सवाल का जवाब नहीं देता है, यही कारण है कि उन्होंने 'enum' का उपयोग किया। – Puppy
@ नवाज स्पष्ट रूप से जवाब जानता है, लेकिन इसे स्पष्ट रूप से नहीं बताया। कुछ कंपाइलर्स में, 'स्थिर कॉन्स int' ** ** संकलित-समय स्थिर नहीं है ** क्योंकि पूर्व-सी ++ 11 मानक को संकलक को हल करने के लिए एक संपूर्ण प्रयास करने की आवश्यकता नहीं होती है। इसलिए, ** फ़ैक्टरियल 'में टेम्पलेट तर्क के रूप में ** इस तरह के' मान' का उपयोग करने का प्रयास कर रहा है, क्योंकि विफल हो सकता है क्योंकि संकलक ने यह निर्णय लिया होगा कि यह मान 'मान' को एक कॉन्स्टेक्सर नहीं बनाया गया हो। –
rwong