2016-12-30 17 views
22

जब मैं एक आधार वर्ग के टेम्पलेट पैरामीटर के रूप में एक टेम्पलेट समारोह गुजरती हैं, लिंकर शिकायत है कि यह समारोह लिंक नहीं कर सकते:त्रुटि संदेश "टेम्पलेट समारोह टेम्पलेट पैरामीटर के रूप में पारित करने के लिए अपरिभाषित संदर्भ"

#include <stdio.h> 

template<int I> inline int identity() {return I;} 
//template<> inline int identity<10>() {return 20;} 

template<int (*fn)()> 
class Base { 
public: 
    int f() { 
     return fn(); 
    } 
}; 

template<int Val> 
class Derived : public Base<identity<10> > { 
public: 
    int f2() { 
     return f(); 
    } 
}; 

int main(int argc, char **argv) { 
    Derived<10> o; 
    printf("result: %d\n", o.f2()); 
    return 0; 
} 

में परिणाम :

$ g++ -o test2 test2.cpp && ./test2 
/tmp/ccahIuzY.o: In function `Base<&(int identity<10>())>::f()': 
test2.cpp:(.text._ZN4BaseIXadL_Z8identityILi10EEivEEE1fEv[_ZN4BaseIXadL_Z8identityILi10EEivEEE1fEv]+0xd): undefined reference to `int identity<10>()' 
collect2: error: ld returned 1 exit status 

अगर मैं विशेषज्ञता बाहर टिप्पणी है, तो कोड को संकलित करता है और लिंक के रूप में उम्मीद। इसके अलावा, अगर मैं के बजाय Base<identity<Val> > से प्राप्त करता हूं, तो कोड की अपेक्षा करता है जैसा कि मैं अपेक्षा करता हूं।

यहाँ का प्रयास करें: http://coliru.stacked-crooked.com/a/9fd1c3aae847aaf7

मैं क्या याद करते हैं?

+3

यह समस्या एक जीसीसी बग प्रतीत हो रहा है: यह संकलित करता है तथा बजना और आईसीसी का उपयोग कर ठीक लिंक एक संभावित काम के आसपास का उपयोग करता है किसी को भी बदलने नहीं एक वर्ग टेम्पलेट identity एक समारोह के बजाय के उपयोग होगा। बीटीडब्ल्यू, नाम _identity() _ आमतौर पर परिवर्तन के लिए उपयोग किया जाता है जहां परिणाम तर्क के समान होता है। –

+0

@ डाइटमार कुहल वेल, 'पहचान () 'रिटर्न' एक्स'। :-) – melpomene

+2

कार्यवाही: 'वर्ग व्युत्पन्न: सार्वजनिक आधार (पहचान <10>)>'। [लाइव डेमो] (http://melpon.org/wandbox/permlink/E4aRHqcZaac7vd3C) –

उत्तर

19

ऐसा लगता है समस्या एक जीसीसी त्रुटि है: कोड को संकलित करता है और बजना, आईसीसी, और ईडीजी दृश्यपटल के साथ लिंक।

template<int I> 
struct identity { 
    operator int() { return I; } 
}; 

template<typename fn> 
class Base { 
public: 
    int f() { 
     return fn(); 
    } 
}; 
+0

फ़ंक्शन टेम्पलेट 'इनलाइन' नहीं बनाना भी काम कर सकता है। क्या लिंकर को डुप्लिकेट टेम्पलेट इंस्टॉलेशन को किसी भी तरह से हटाना नहीं है? – Etherealone

9

एक typedef में इसे बाहर भारोत्तोलन यह संकलन करता है, अर्थात

typedef Base< identity<10> > base10; 

मैं काफी यकीन है कि क्यों यह सीधे वर्ग परिभाषा काम नहीं करता है में कर नहीं हूँ।

http://coliru.stacked-crooked.com/a/f00b4f4d1c43c2b0

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