2010-09-04 13 views
20

यह संकलन करने में विफल क्यों होता है? (छ ++ - 4,5)सी ++ टेम्पलेट फ़ंक्शन का पता

template < typename U > 
static void h() { 
} 

int main() { 
    auto p = &h<int>; // error: p has incomplete type 
} 

संपादित:

template < typename U > 
static void h() { 
} 

int main() { 
    typedef decltype (&h<int>) D; 
    D p = &h<int>; // works 
} 
+1

विजुअल स्टूडियो 2010 पर ठीक से संकलित करता है। यह संभवतः जीसीसी में एक गड़बड़ है। आप क्या कोशिश कर सकते हैं 'decltype (& h ) पी = और एच ;' – Puppy

+0

कम से कम G ++ 4.6 के साथ काम करता है। – Maister

+0

@DeadMG: "ऑटो" के बिना टाइपिफ़ की आवश्यकता नहीं है, 'शून्य (* पी)() = और एच ;' संकलित भी होगा। – doc

उत्तर

13

प्रयास करें C++ 0x में यह काम करने के लिए गारंटी है। हालांकि सी ++ 03 में यह काम नहीं कर रहा था (प्रारंभकर्ता भाग, जो है) और कुछ कंपाइलर स्पष्ट रूप से इसका समर्थन नहीं करते हैं।

इसके अलावा, मुझे याद है कि C++ 0x शब्द स्पष्ट नहीं है कि &h<int> के साथ क्या होता है जब यह फ़ंक्शन टेम्पलेट के लिए तर्क होता है और संबंधित पैरामीटर घटाया जाता है (यह auto का अनुवाद अवधारणात्मक रूप से किया जाता है)। इरादा यह है कि, यह मान्य है। this defect report देखें जहां उन्होंने शब्दलेखन किया, उदाहरण "निको जोसुटिस" और उनके अंतिम उदाहरण।

एक और नियम है कि शब्द लागू करता है लेकिन कंपाइलर्स सही ढंग से कार्यान्वित नहीं कर रहे हैं। उदाहरण के लिए, see this clang PR

0

यह संकलन नहीं है क्योंकि 'पी' के प्रकार संकलक है जो बहुत जरूरी करने के लिए नहीं जाना जाता है: यहाँ एक काम के आसपास है सी ++ में कुछ अन्य भाषाओं के विपरीत।

template < typename U > 
static void h() { 
} 

int main() { 
    auto void (*p)() = &h<int>; 
} 
+1

स्वचालित प्रकार की कटौती के लिए 'ऑटो' कीवर्ड का उपयोग किया जाता है। एक सी ++ 0 एक्स सुविधा। – dirkgently

+0

ठीक है, लेकिन मेरे असली कोड में, एच यू और अन्य टेम्पलेट्स के आधार पर कई अन्य पैरामीटर लेता है, और मैं उन्हें सभी निर्दिष्ट नहीं करना चाहता, क्योंकि पी के प्रकार को कंपाइलर को जाना जाना चाहिए। – Thomas

+1

@dirkgenly: ओह। मैं अभी भी सी ++ 03 पर हूं जहां 'ऑटो' स्वचालित चर के लिए है – Chubsdad

0

क्योंकि जीसीसी व्यवहार करता है टेम्प्लेट की गई अतिभारित एक के रूप में समारोह का प्रयास करें

auto p = static_cast<void(*)()>(& h<int>); 

। जीसीसी के दृष्टिकोण से ऐसा लगता है कि आपके पास h(int param) और h(float param) होगा - जिसे संकलक को चुनना है?

मैंने देखा कि जीसीसी के पुराने संस्करणों में समस्या क्या थी, लेकिन मैं इसे अधिक verbosely समझाने की कोशिश करूंगा। जीसीसी इस प्रकार को कम नहीं कर सका, क्योंकि टेम्पलेटेड फ़ंक्शन को अधिभारित किया गया था। यह मूल रूप से था जैसे आप निम्नलिखित होंगे:

void h(int) 
{ 
} 

void h(float) 
{ 
} 

void (*p)(int) = & h; //ok 
void (*p)(float) = & h; //ok 
auto p = & h; //error: which version of h? 

जीसीसी h<int> बस अतिभारित T पैरामीटर के आधार पर अंतहीन विकल्पों के साथ h समारोह की तरह था। प्रश्न में दिए गए कोड के साथ यह ओ.के. था। निम्न कार्य करें: (यही कारण है कि मैं typedefed नहीं मिलता है "काम के आसपास" है)

void (*p)() = & h<int>; 

के रूप में मैंने सोचा था कि ओपी C++ 11 auto कीवर्ड का उपयोग करने के रूप में एक टैग ने सुझाव दिया था, मैंने h<int> को void(*)() पर स्थिर रूप से कास्ट किया, जो कि जीसीसी की चाल करने के लिए केवल तरह का ऑपरेशन है, क्योंकि यह टेम्पलेट किए गए कार्यों और auto से सही तरीके से निपटने में सक्षम नहीं था।

कार्य void h<int>() और void h<float>() पाठ्यक्रम एक ही सूचक प्रकार के साथ विभिन्न कार्यों की तरह व्यवहार की होनी चाहिए और h समारोह के संस्करणों को ओवरलोड नहीं।जब instantiated वे void hInt() और void hFloat() की तरह व्यवहार करना चाहिए और तुम यहाँ की तरह ऑटो उपयोग करने के लिए सक्षम होना चाहिए:

void hInt() 
{ 
} 

void hFloat() 
{ 
} 

auto p = hInt; 
p = hFloat; 

लेकिन जीसीसी के लिए किसी कारण से वे h की अतिभारित संस्करणों की तरह थे।

कृपया डाउनवॉट्स का कारण दें।

+0

मैं डाउनवॉटर नहीं हूं :) किसी भी तरह से मैं आपके तर्क को समझने के लिए निश्चित नहीं हूं: चूंकि आप एक संकलित समय के लिए static_casting हैं, ऑटो के लिए उपयोग क्या है? – Francesco

+0

@ फ्रांसेस्को: बिना किसी कास्ट जीसीसी के त्रुटि में फेंकता है "कथन ओवरलोडेड फ़ंक्शन के पते को हल नहीं कर सकता"। ओवरलोडेड फ़ंक्शन (जैसे 'शून्य एच (इंट)' और 'शून्य एच (फ्लोट)' के मामले में आपको वही त्रुटि मिल जाएगी, जिसमें केस कंपाइलर यह निर्धारित करने में असमर्थ है कि कौन सा संस्करण चुनना है जब यह '& h' कथन पाता है । किसी कारण से (मुझे लगता है कि यह टेम्पलेट तर्क खोज के साथ कुछ है) टेम्पलेटेड फ़ंक्शन का इलाज उसी तरह किया जाता है जैसे ओवरलोडेड। मैंने अधिभारित कार्यों के मामले में static_cast का उपयोग करने के बाद इसे संकलित करना शुरू कर दिया। 'ऑटो' का उपयोग 'पी' प्रकार को कम करने के लिए किया जाता है। – doc

+0

@ फ्रांसेस्को: उन्हें 'typedef' के साथ एक static_cast के साथ एक ही परिणाम मिला। मैंने सोचा कि वह सी ++ 0x 'ऑटो' कीवर्ड चाहता था ... – doc

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