2012-04-09 9 views
10

एक बड़े कार्यक्रम के लिए एक विशेषता वर्ग के हिस्से के रूप में, मैंने एक स्थैतिक वर्ग चर बनाने का प्रयास किया, जिसमें संलग्न वर्ग टेम्पलेट को तत्काल के प्रकार के आधार पर एक अलग मूल्य हो सकता था।जी ++ कंपाइलर त्रुटि या दोषपूर्ण कोड? : "गैर-टेम्पलेट की टेम्पलेट परिभाषा"

मैं प्रासंगिक कोड सरल बना दिया है मैं किस बारे में बात कर रहा हूँ के एक नंगे हड्डियों उदाहरण उत्पादन करने के लिए:

#include <iostream> 
#include <string> 
#include <type_traits> 

template <class T, class Enable = void> 
struct Foo; 

template <class T> 
struct Foo<T, 
    typename std::enable_if<std::is_integral<T>::value>::type 
> 
{ 
    static std::string message; 
}; 

template <class T> 
struct Foo<T, 
    typename std::enable_if<std::is_floating_point<T>::value>::type 
> 
{ 
    static std::string message; 
}; 

template <class T, class Enable> 
std::string Foo<T, Enable>::message; 
जीसीसी 4.6 के साथ

, यह एक संकलक त्रुटि देता है: template definition of non-template ‘std::string Foo<T, Enable>::message। समस्या पिछले दो पंक्तियों के कारण होती है, जहां मैं केवल स्थिर चर std::string Foo<T, Enable>::message को परिभाषित कर रहा हूं।

मुझे उलझन में है कि यह क्यों हो रहा है। यदि मैं पिछले दो पंक्तियों को छोड़ देता हूं (लेकिन निश्चित रूप से लिंकर त्रुटियों का कारण बनता है) संकलक त्रुटि दूर हो जाती है।) क्या यह जीसीसी के साथ एक कंपाइलर त्रुटि है?

+2

+1 "एक नंगे-हड्डियों उदाहरण" के लिए +1। http://sscce.org/। –

+0

आपको

+0

@ वॉन शामिल करने की आवश्यकता है, यह समस्या नहीं है, लेकिन मैंने कोड स्निपेट अपडेट किया है। – Channel72

उत्तर

10

यह केवल काम करता है जब अपने टेम्पलेट मापदंडों आंशिक विशेषज्ञता से मेल खाते हैं:

template <class T> 
std::string Foo<T, 
    typename std::enable_if<std::is_integral<T>::value>::type 
>::message; 

template <class T> 
std::string Foo<T, 
    typename std::enable_if<std::is_floating_point<T>::value>::type 
>::message; 

यह सी ++ 03 मानक की धारा 14.5.4.3 में निर्दिष्ट है। विचार यह है कि आंशिक विशेषज्ञता एक नया टेम्पलेट है और बाहरी रूप से परिभाषित सदस्यों के टेम्पलेट पैरामीटर को कक्षा परिभाषा के टेम्पलेट पैरामीटर से मेल खाना है ताकि यह पता चल सके कि सदस्य किस टेम्पलेट के साथ जाता है।

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

+0

यह केवल उस मामले में क्यों काम करता है? – SirGuy

+0

क्या कोई कारण है कि एक परिभाषा यहां काम नहीं करती है? क्या यह सी ++ मानक, या जी ++ में एक क्विर्क द्वारा अनिवार्य है? – Channel72

+0

@GuyGreer: मुझे लगता है क्योंकि _message_ स्थिर फ़ील्ड सामान्य टेम्पलेट के लिए घोषित नहीं किया गया है (केवल कुछ विशेषज्ञताओं के लिए)। निश्चित रूप से – user396672

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