2011-01-16 39 views
15

निरंतर my journey into the world of variadic templates, मुझे एक और समस्या का सामना करना पड़ा। ,एकाधिक टेम्पलेट पैरामीटर पैक के साथ आंशिक टेम्पलेट विशेषज्ञता

template < template < typename ... > class T, typename ...Args > 
struct foo< T<Args...> > 
{ 
    //specialized implementation 
}; 
इस के साथ

foo<int> डिफ़ॉल्ट कार्यान्वयन और foo< std::tuple< int, char > > के अनुरूप होगा:

template < typename T > 
struct foo 
{ 
    //default implementation 
}; 

यह आंशिक रूप से इस तरह variadic टेम्पलेट instantiations के लिए यह विशेषज्ञ के लिए संभव है:

निम्नलिखित टेम्पलेट वर्ग मानते हुए विशेष कार्यान्वयन के लिए।

हालांकि, कई टेम्पलेट पैरामीटर का उपयोग करते समय चीजें अधिक जटिल हो जाती हैं। उदाहरण के लिए, अगर हम निम्न टेम्पलेट वर्ग

template < typename T, typename U > 
struct bar {}; 

है और हम आंशिक रूप से यह विशेषज्ञ के रूप में हम foo के लिए किया था चाहते हैं, हम

template < template < typename ... > class T, typename ...TArgs, 
      template < typename ... > class U, typename ...UArgs > 
struct bar< T<TArgs...>, U<UArgs...> > {}; 

//This would correspond to the specialized version with 
//T=std::tuple, 
//TArgs=int,char 
//U=std::tuple, 
//UArgs=float 
bar< std::tuple< int, char >, std::tuple<float> > b; 

दरअसल ऐसा नहीं कर सकते, अगर मैं सही हूँ, हम केवल कर सकते हैं एक टेम्पलेट पैरामीटर पैक है और इसे पैरामीटर सूची के अंत में स्थित होना चाहिए। मैं समझता हूं कि यह टेम्पलेट घोषणाओं में क्यों अनिवार्य है, लेकिन कुछ आंशिक टेम्पलेट विशेषज्ञता (उपरोक्त उदाहरण की तरह) के लिए, यह कोई मुद्दा नहीं होना चाहिए।

क्या एकाधिक टेम्पलेट पैरामीटर पैक के साथ आंशिक टेम्पलेट विशेषज्ञता प्राप्त करना संभव है?


संपादित: अब मैं मूर्ख महसूस ... कोड मैं ऊपर दे दी है (कम से कम जीसीसी 4.5 के साथ) पूरी तरह से संकलित करता है। मेरे पास संकलित त्रुटि एकाधिक पैरामीटर पैक की वजह से नहीं थी, लेकिन सदस्य फ़ंक्शन पैरामीटर के रूप में उनके उपयोग के कारण। bar का आंशिक विशेषज्ञता में, मैं एक सदस्य समारोह है कि दोनों TArgs और UArgs पैरामीटर लेता है परिभाषित करने की कोशिश की:

template < template < typename ... > class T, typename ...TArgs, 
      template < typename ... > class U, typename ...UArgs > 
struct bar< T<TArgs...>, U<UArgs...> > 
{ 
    void method(TArgs... targs, UArgs... uargs) //compile error here 
    { 
    } 
}; 

सदस्य समारोह घोषणा पर, जीसीसी मुझे त्रुटि

देता

मापदंडों पैक किया जाना चाहिए पैरामीटर सूची के अंत में।

जहां तक ​​मैं कह सकता हूं, संकलक किसी दिए गए टेम्पलेट तत्काल के लिए सही सदस्य फ़ंक्शन को परिभाषित करने में सक्षम होना चाहिए, उदा। bar< std::tuple< int, char >, std::tuple<float> > में सदस्य फ़ंक्शन void method(int, char, float) होना चाहिए। क्या मुझसे कुछ गलत हो रही है? या क्या मैं ऐसा कुछ करने की कोशिश कर रहा हूं जो संभव नहीं है? यदि हां, तो क्या कोई अच्छा कारण नहीं है कि यह संभव नहीं है?

+0

नीट, मुझे नहीं पता था कि आप टेम्पलेट सूची के तत्वों को टेम्पलेट्स के रूप में विशेषज्ञ/निर्दिष्ट (निर्दिष्ट) कर सकते हैं। – JAB

उत्तर

6

शायद यह उत्तर सीधे आपके प्रश्न को स्पष्ट नहीं करेगा, लेकिन जब मैंने परीक्षण किया तो विचारधारा (gcc-4.5.1) पर संकलित निम्न कोड।

#include <cstdio> 
#include <tuple> 

template< class, class > struct S { 
    S() { puts("primary"); } 
}; 

template< 
    template<class...> class T, class...TArgs 
, template<class...> class U, class...UArgs 
> 
struct S< T<TArgs...>, U<UArgs...> > { 
    S() { puts("specialized"); } 
}; 

int main() 
{ 
    S< int, int > p;          // "primary" 
    S< std::tuple< int, char >, std::tuple<float> > s; // "specialised" 
} 

मुझे यकीन है कि इस कोड को सख्ती से अधिक अनुरूप है नहीं कर रहा हूँ, लेकिन जहाँ तक मैं N3225 14.5.3 पढ़ा, मैं बयान जो कि टेम्पलेट पैरामीटर पैक पिछले टेम्पलेट हो गया है का उल्लेख नहीं पा सके पैरामीटर।

संपादित करें:
मैं N3225 पुन: पढ़ने और पाया निम्नलिखित बयानों:

8.3.5/4 पैरामीटर-घोषणा-खंड एक अंडाकार या एक समारोह पैरामीटर पैक के साथ समाप्त हो जाता है (14.5.3), तर्कों की संख्या के बराबर होगी या पैरामीटर की संख्या से अधिक होगी जिनके पास डिफ़ॉल्ट तर्क नहीं है और पैरामीटर पैक कार्य नहीं कर रहे हैं।

14.8.2.5/10 [नोट: एक फ़ंक्शन पैरामीटर पैक केवल पैरामीटर-घोषणा सूची (8.3.5) के अंत में हो सकता है। अंत टिप्पणी]

तो, जैसा कि आप उल्लेख किया है, समारोह पैरामीटर पैक पिछले पैरामीटर दुर्भाग्य से हो गया है।
क्लास टेम्पलेट का एक गैर-टेम्पलेट सदस्य फ़ंक्शन उस वर्ग के लिए सामान्य कार्य है जब इसे तत्काल (पूरी तरह से विशिष्ट) किया जाता है। तो मेरी इच्छा है कि इस प्रश्न में कोड को विशेष मामले के रूप में तार्किक रूप से संकलित किया जा सके।

+0

आप सही हैं, कोड पूरी तरह संकलित है! जो मुद्दा मैं जोड़ता हूं वह वास्तव में थोड़ा अलग था, मैं सवाल संपादित करूंगा ... असुविधा के लिए क्षमा करें ... –

+0

@LucTouraille: चिंता न करें :-) यह मेरे लिए अच्छा आत्म शैक्षिक अवसर था। –

+0

कुछ मुझे बनाता है। सोचो कि उद्धरण यहां लागू करने का इरादा नहीं है क्योंकि दोनों पैरामीटर पैक पहले से ही ज्ञात हैं और केवल विस्तारित करने की आवश्यकता है। यह मुझे आश्चर्य नहीं करेगा अगर क्लैंग इस कोड को स्वीकार करेगा –

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