प्रश्न दोबारा दोहराएं: आपके पास दो कार्य हैं जो T
प्रकार का पैरामीटर लेते हैं। कोई अपना पैरामीटर टेम्पलेट पैरामीटर के रूप में लेता है, और दूसरा 'सामान्य' पैरामीटर के रूप में लेता है। मैं tfunc
और func
के बजाय दो फ़ंक्शन funcT
और funcN
पर कॉल करने जा रहा हूं। आप funcN
से funcT
पर कॉल करने में सक्षम होना चाहते हैं। उत्तरार्द्ध को constexpr
के रूप में चिह्नित करने से मदद नहीं मिलती है।
constexpr
के रूप में चिह्नित कोई भी फ़ंक्शन संकलित करने योग्य होना चाहिए जैसे कि constexpr
वहां नहीं था। constexpr
फ़ंक्शंस एक छोटे से स्किज़ोफ्रेनिक हैं। वे केवल कुछ परिस्थितियों में पूर्ण निरंतर अभिव्यक्ति के लिए स्नातक हैं।
यह funcN लागू करने के लिए एक सरल तरीके से रन टाइम पर चलाने के लिए, के रूप में यह टी की सभी संभव मूल्यों के लिए काम करने के लिए सक्षम होने के लिए की आवश्यकता होगी संभव नहीं होगा। इसके लिए कंपाइलर को tfunc
के कई उदाहरणों को तत्काल करने की आवश्यकता होगी, एक टी के प्रत्येक मान के लिए। लेकिन यदि आप टी के एक छोटे से सबसेट के साथ रहने के इच्छुक हैं तो आप इसके आसपास काम कर सकते हैं।ग्राम में ++ 1024 के एक टेम्पलेट प्रत्यावर्तन सीमा नहीं है, ताकि आप आसानी से इस कोड के साथ टी के 1024 के मानों का प्रबंधन कर सकते हैं:
#include<iostream>
#include<functional>
#include<array>
using namespace std;
template <typename T, T t>
constexpr T funcT() {
return t + 10;
}
template<typename T, T u>
constexpr T worker (T t) {
return t==0 ? funcT<T,u>() : worker<T, u+1>(t-1);
}
template<>
constexpr int worker<int,1000> (int) {
return -1;
}
template <typename T>
constexpr T funcN(T t)
{
return t<1000 ? worker<T,0>(t) : -1;
}
int main()
{
std::cout << funcN(10) << std::endl;
array<int, funcN(10)> a; // to verify that funcN(10) returns a constant-expression
return 0;
}
यह एक समारोह worker
जो रिकर्सिवली किसी टेम्प्लेट में 'सामान्य' पैरामीटर t
में परिवर्तित कर देंगे का उपयोग करता है पैरामीटर u
, जो तब यह tfunc<T,u>
को तत्काल और निष्पादित करने के लिए उपयोग करता है।
महत्वपूर्ण लाइन return funcT<T,u>() : worker<T, u+1>(t-1);
यह सीमाएँ हैं है। यदि आप long
, या अन्य अभिन्न प्रकारों का उपयोग करना चाहते हैं, तो आपको एक और विशेषज्ञता जोड़नी होगी। जाहिर है, यह कोड केवल 0 और 1000 के बीच टी के लिए काम करता है - सटीक ऊपरी सीमा शायद संकलक-निर्भर है। एक अन्य विकल्प 2 में से प्रत्येक बिजली के लिए एक अलग कार्यकर्ता समारोह के साथ, एक तरह के द्विआधारी खोज का उपयोग हो सकता है:
template<typename T, T u>
constexpr T worker4096 (T t) {
return t>=4096 ? worker2048<T, u+4096>(t-4096) : worker2048<T, u>(t);
}
मुझे लगता है कि इस टेम्पलेट-प्रत्यावर्तन सीमा के आसपास काम करेंगे, लेकिन यह अभी भी एक बहुत की आवश्यकता होगी बड़ी संख्या में तत्कालताएं और संकलन बहुत धीमा कर देगा, अगर यह बिल्कुल काम करता है।
एफडब्ल्यूआईडब्ल्यू, क्लैंग 3.1 हेड भी वही त्रुटियों को फैलाता है। – Xeo