2012-04-25 17 views
5

मैं समझ नहीं क्यों निम्नलिखित कोड ठीक संकलित:सी ++ निहित मापदंडों के साथ समारोह खाका instantiaion

#include <iostream>                 

void bar(int x) {                 
    std::cout << "int " << x << std::endl;            
}                     

void bar(double x) {                 
    std::cout << "double " << x << std::endl;           
}                     

template <typename A, typename B> // Note the order of A and B.            
void foo(B x) {                  
    bar((A)x);                   
}                     

int main() {                   
    int x = 1;                   
    double y = 2;                  

    foo<int>(x);  // Compiles OK.                
    foo<double>(y);  // Compiles OK.            

    return 0;                   
} 

लेकिन अगर मैं A और नीचे के रूप में B का क्रम बदलने, तो यह संकलन नहीं होगा:

#include <iostream>                 

void bar(int x) {                 
    std::cout << "int " << x << std::endl;            
}                     

void bar(double x) {                 
    std::cout << "double " << x << std::endl;           
}                     

template <typename B, typename A> // Order of A and B are switched. 
void foo(B x) {                  
    bar((A)x);                   
}                     

int main() {                   
    int x = 1;                   
    double y = 2;                  

    foo<int>(x);  // error: no matching function for call to ‘foo(int&)’ 
    foo<double>(y);  // error: no matching function for call to ‘foo(double&)’                

    return 0;                   
}  

संपादित करें: तदर्थ स्पष्टीकरण स्वागत है, लेकिन बेहतर होगा अगर किसी को सही क्या कल्पना का कहना है सकते हैं। कहते हैं। धन्यवाद!

+1

कंपाइलर आपके पहले उदाहरण में बी के प्रकार को फू कन्स्ट्रक्टर (प्रकार बी) में पारित पैरामीटर से अनुमान लगा सकता है। दूसरे उदाहरण में, ऐसी कोई अनुमान नहीं बनाई जा सकती है, क्योंकि आपूर्ति किए गए टेम्पलेट पैरामीटर बी है, और यह कन्स्ट्रक्टर पैरामीटर भी है। ए के प्रकार सबूत में कहीं भी नहीं है। – Stabledog

उत्तर

7

पहले एक में, संकलक जानता है कि A है int क्योंकि आप विशेष रूप से foo<int> साथ तो यह बताओ, और यह जानता है कि B भी पैरामीटर है कि आप इसे पारित की वजह से int है। तो A और B दोनों ज्ञात या कटौती की जा सकती हैं (आप कह सकते हैं: A, B निहित है)।

हालांकि, दूसरे में, B पहले आता है और A पैरामीटर सूची में प्रकट नहीं होता है, संकलक यह नहीं बता सकता कि A क्या है और आपको एक त्रुटि देता है। आप स्पष्ट रूप से यह कह रहे हैं क्या Bfoo<int> साथ है, और फिर पैरामीटर पारित भी एक B जो, कॉल पर, एक int जो B के अपने पिछले स्पष्ट परिभाषा से सहमत है परोक्ष है, लेकिन कोई जिक्र नहीं A से बना है, या स्पष्ट रूप से, इसलिए संकलक को रोकना और त्रुटि होना चाहिए।

आपको इसके लिए मानक की आवश्यकता नहीं है, यह सामान्य ज्ञान है। पृथ्वी पर क्या A दूसरे में होगा?

हालांकि इस सवाल को पूछने के लिए धन्यवाद, क्योंकि मुझे एहसास नहीं हुआ कि आप स्पष्ट रूप से कुछ पैरामीटर निर्दिष्ट कर सकते हैं और इससे पहले पैरामीटर सूची में दूसरों को निर्दिष्ट कर सकते हैं।

+0

तो, यह एक सवाल बन गया है कि कल्पना क्या है। 'ए' और 'बी' निर्धारित किए जाने के संबंध में कहते हैं। कंपाइलर पहले इनपुट तर्क के कारण 'बी' निर्धारित कर सकता था, फिर 'foo ' से' ए' को समझें। फिर, दोनों टेम्पलेट पैरामीटर दूसरे मामले में भी निर्धारित किए जाते हैं। – kirakun

+1

@ किराकुन वास्तव में नहीं। 'ए' और' बी' केवल तभी निर्धारित किया जा सकता है यदि आप '<> 'में किसी प्रकार को निर्दिष्ट करते हैं, या उन सभी जो' <>' में निर्दिष्ट नहीं हैं, पैरामीटर सूची में हैं, इसलिए संकलक इसे कम कर सकता है कॉल से टाइप करें। दूसरे में, 'ए' न तो स्पष्ट रूप से '<>' में निर्दिष्ट है और न ही यह पैरामीटर सूची में है, इसलिए इसे ज्ञात नहीं किया जा सकता है। –

+1

@ किराकुन सिर्फ इसलिए कि आप पैरामीटर सूची में से एक डालते हैं इसका मतलब यह नहीं है कि जब आप '<> 'के बीच चीजें डालने लगते हैं तो यह छोड़ दिया जाता है। वे अभी भी क्रम में हैं, वे सूची 'टेम्पलेट <टाइपनाम बी, टाइपनाम ए>' में हैं, इसलिए 'बी' पहले है, और फिर' ए' दूसरा, हमेशा, फ़ंक्शन लेने वाले तर्कों के बावजूद। –

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