2011-08-03 6 views
6

मैं वंदेवोर्डे और जोसुटिस के "सी ++ टेम्पलेट्स पूर्ण गाइड" पढ़ रहा हूं (जो कि बहुत अच्छा लगता है)। यह दावा (धारा 3.3) गलत लगता है and is not in the published errata:क्या यह पाठ्य पुस्तक गलत है? कुछ सदस्य फ़ंक्शंस को विशेषज्ञता देना, लेकिन अन्य नहीं

यदि आप कक्षा टेम्पलेट का विशेषज्ञ हैं, तो आपको सभी सदस्य कार्यों को भी विशेषज्ञ बनाना होगा। यद्यपि ऐसा करने के बाद, एक सदस्य कार्य को विशेषज्ञता देना संभव है, फिर भी आप पूरी कक्षा का विशेषज्ञ नहीं बन सकते हैं।

फिर भी जीसीसी टेम्पलेट पर निम्नलिखित compiles

<typename T> 
struct C { 
    T foo(); 
    T bar(); 
}; 

template <> 
struct C<int> { 
    int foo(); 
    int bar() {return 4;} 
}; 

template <typename T> 
T C<T> :: foo() {return 0;} 

template <typename T> 
T C<T> :: bar() {return 1;} 

int C<int> :: foo() {return 2;} 

template <> 
float C<float> :: bar() {return 3;} 

#include <cassert> 

int main() { 
    C<int> i; 
    C<float> f; 
    assert (2 == i .foo()); 
    assert (0 == f .foo()); 
    assert (4 == i .bar()); 
    assert (3 == f .bar()); 
} 

मैं C<int>::foo विशेष है और C<float>::bar तो पाठ्यपुस्तक गलत है, मानक से परे जा रहा जीसीसी है, या मैं पूरी स्थिति गलतफहमी रहा हूँ?

धन्यवाद।

+0

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

उत्तर

5

आप ऐसा नहीं कर सकते:

template <typename T> struct C 
{ 
    T foo()  { return 0;} 
    T bar()  { return 1;} 
}; 

// partial specialization of foo on C<int> 
template <> 
int C<int> :: foo() {return 2;} 

// partial specialization of bar on C<float> 
template <> 
float C<float> :: bar() {return 3;} 

// will not compile, C<int> already partially specialized 
template <> 
struct C<int> 
{ 
    int foo() {return 10;} 
    int bar() {return 10;} 
}; 
+1

यह एक साधारण पुनर्वितरण त्रुटि है, टेम्पलेट्स के साथ कुछ भी नहीं करना है। क्या मैं उलझन में हूं? बस क्योंकि यह टेम्पलेट के संदर्भ में उल्लेख किया गया है? अच्छा दुख ... – spraff

+0

इस संदर्भ में आप इसे हां जैसे सोच सकते हैं। यदि आप 'सी 'की विशेषज्ञता में' foo()' के कार्यान्वयन को हटाते हैं, तो यह केवल इस फ़ंक्शन के कार्यान्वयन के रूप में आंशिक विशेषज्ञता का इलाज करेगा। – Chad

4

नहीं, पुस्तक गलत नहीं है। आपकी समझ, है मुझे डर है :)

हूँ इस मामले आप केवल 1 सदस्य समारोह पास विशेष में - के लिए C<float>

C<int> और bar के लिए foo अब आप स्पष्ट रूप से C<int> या C<float> विशेषज्ञ नहीं कर सकते। लेकिन आप विशेषज्ञ कर सकते हैं C<char>

+0

कृपया मेरा अपडेट किया गया प्रश्न देखें। अब मैंने 'सी 'के लिए एक फ़ंक्शन (बार) विशिष्ट किया है और' सी 'के लिए पूर्ण विशेषज्ञता दी है - क्या *** *** *** पाठ्यपुस्तक का विरोधाभास नहीं है? – spraff

+0

नहीं, सी :: foo() का आपका "आंशिक विशेषज्ञता" वास्तव में पूरी तरह से विशिष्ट संस्करण की परिभाषा है। विवरण के लिए नीचे मेरा जवाब देखें। – Chad