2012-02-29 26 views
5

मैं बस एक बाइनरी शाब्दिक operator ""_b हैक करने की कोशिश कर रहा था, लेकिन रिकर्सन को समाप्त करने की कोशिश कर रहा था। एक फ़ंक्शन को परिभाषित करने के लिए जिसे एक खाली स्पष्ट टेम्पलेट पैरामीटर सूची का उपयोग करके बुलाया जा सकता है, जो पैरामीटर पैक अधिभार के साथ संघर्ष नहीं करता है? फिर, प्रेरणा: कुछ खाली बेकार के लिए खाली पैक विस्तार से मेल खाते हैं।क्या एक खाली मूल्य पैक विस्तार एक प्रकार पैक या वैकल्पिक प्रकार पैरामीटर से मेल खाता है?

लेकिन जीसीसी शिकायत करता है कि रिक्त तर्क सूची के किसी भी प्रकार के प्रकार पैरामीटर सूची के स्पष्ट रूप से आवश्यक प्रकारों से सहमत नहीं हैं। क्या यह इस तरह से काम करना चाहिए?

template< char head, char ... tail > 
constexpr unsigned long long parse_binary() { 
    return ((head - '0') << sizeof ... (tail)) 
     + parse_binary< tail ... >(); // Error: no overload for termination. 
} 

template< typename = void > // I want this to match an empty pack of chars. 
// template< short = 0 > // even this would do. 
constexpr unsigned long long parse_binary() { 
    return 0; 
} 

template< char ... digits > 
constexpr unsigned long long operator ""_b() { 
    return parse_binary< digits ... >(); 
} 

#include <iostream> 

int main() { 
    std::cout << 010101_b << '\n'; 
} 

नोट: प्रश्न operator ""_b लागू नहीं कर रहा है। उस समस्या को पैरामीटर सूची में पैक का विस्तार करके हल किया जा सकता है, और std::integral_constant प्रकारों को पास कर सकता है।

नोट 2: यह कोड वास्तव में मामूली समायोजन के साथ काम करता है; नीचे मेरा जवाब देखें। लेकिन यह सीधे सवाल को संबोधित नहीं करता है। हम्म, शायद मुझे जवाब देने के बजाय इसे संपादित करना चाहिए था ...

+0

सामान्य तौर पर आप मूल टेम्पलेट 'टेम्पलेट बनाने <चार सिर, चार पहले, चार ... पूंछ> द्वारा' प्रत्यावर्तन समाप्त कर सकते हैं, और समाप्ति के लिए 'टेम्पलेट ' का उपयोग करें - लेकिन मुझे लगता है कि आप जो पूछ रहे हैं वह नहीं है। –

+1

@ BjörnPollex No, फिर दो तर्कों को पारित करना संदिग्ध होगा। पैक खाली होने की अनुमति है। एक 'टेम्पलेट < char head >' और एक 'टेम्पलेट 'चाल करेगा, लेकिन हाँ, यह सवाल नहीं है। – Potatoswatter

उत्तर

0

इस तरह के मुश्किल के अनुपालन पर कोई आधिकारिक शब्द मिलान, लेकिन दिया गया कोड काम करता है यदि दो ओवरलोड ट्रांसपोज़ किए जाते हैं।

दूसरा, ओवरलोडिंग अधिभार पहले के लिए दृश्यमान नहीं है क्योंकि पहला नाम टेम्पलेट-परिभाषा समय पर हल करता है। टेम्पलेट पैरामीटर पर निर्भर फ़ंक्शन कॉल केवल तत्काल समय तक लुकअप को स्थगित कर दिया गया है।

बस स्पष्ट होना, इस काम करता है:

template< typename = void > // Define this one first! 
constexpr unsigned long long parse_binary() { 
    return 0; 
} 

template< char head, char ... tail > 
constexpr unsigned long long parse_binary() { 
    return ((head - '0') << sizeof ... (tail)) 
     + parse_binary< tail ... >(); // Bingo: overload found. 
} 
+0

सीआई ++ में iirc 11 हमारे पास एक स्पष्ट बुलेट है कि फ़ंक्शन का नाम निर्भर है यदि यह एक टेम्पलेट आईडी है और टेम्पलेट तर्कों में से एक निर्भर है। अब यह जानने के लिए कि यह एक टेम्पलेट आईडी है, पहले संकलक को इसे टेम्पलेट पर देखना होगा, लेकिन मैं zhink soesnt एक दूसरी तत्काल समय लुकअप को रोकता हूं। –

+0

हाँ मैंने सत्यापित किया कि यह एक जीसीसी बग है: "parse_binary < tail ... >()" को "parse_binary" के तत्काल-निर्भर लुकअप भी करना चाहिए। –

+0

@ जोहान्सचैब-लिटब: दिलचस्प! क्या आपने बग फाइल किया था? – Potatoswatter

4

क्या एक चरित्र में रिकर्सन को समाप्त करना बेहतर नहीं होगा?

template<char Ch> 
constexpr unsigned long long parse_binary(){ 
    return Ch - '0'; 
}; 

// second head to disambiguate 
template< char head1, char head2, char ... tail > 
constexpr unsigned long long parse_binary() { 
    return ((head1 - '0') << sizeof ... (tail)+1) + parse_binary< head2, tail ... >(); 
} 

किसी भी मामले में, समस्या यह है कि parse_binary के लिए शून्य वर्ण, variadic संस्करण से पहले घोषित करने के रूप में अच्छी तरह से बजना बताते हैं की जरूरत है:

error: call to function 'parse_binary' that is neither visible in 
     the template definition nor found by argument-dependent lookup 

// call trace... 

note: 'parse_binary' should be declared prior to the call site 
     constexpr unsigned long long parse_binary() { 
+0

एलओएल। मैंने बस नीचे स्क्रॉल करने से पहले Björn को अपना जवाब लिखा था। जैसा कि मैंने नोट में कहा था, यह पैरामीटर पैक के बारे में एक सवाल है, बाइनरी साहित्य को लागू नहीं करता है। सुरुचिपूर्ण समाधान फ़ंक्शन पैरामीटर सूची में पैक का विस्तार करना है। – Potatoswatter

+0

आह, हां, आपको ओवरलोड उम्मीदवार सेट का विस्तार करने की अनुमति नहीं है जब तक अधिभारित नाम एडीएल टेम्पलेट पैरामीटर पर निर्भर न हो। आह, चैट में ल्यूक की टिप्पणी के साथ संयुक्त, मुझे लगता है कि अब मैं समझता हूं। – Potatoswatter

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