2009-06-27 10 views
5

मेरे पास टेम्पलेट फ़ंक्शन "तुलना" नीचे परिभाषित किया गया है।टेम्पलेट तत्काल त्रुटि

#include<iostream> 
using namespace std; 

template<typename T> 
void compare(const T&a, const T& b) 
{ 
    cout<<"Inside compare"<<endl; 
} 

main() 
{ 
compare("aa","bb"); 
compare("aa","bbbb"); 
} 

जब मैं उसी लंबाई के स्ट्रिंग अक्षर के साथ तुलना करता हूं, तो संकलक शिकायत नहीं करता है। जब मैं इसे अलग-अलग लंबाई के अक्षर के साथ करता हूं, तो यह कहता है "त्रुटि: तुलना करने के लिए कॉल के लिए कोई मिलान करने वाला फ़ंक्शन नहीं है (कॉन्स char [3], कॉन्स char [5])"

मैं उलझन में हूं क्योंकि तुलना फ़ंक्शन को तुरंत चालू किया जाना चाहिए वर्ण सरणी के बजाय चरित्र सूचक। सचमुच पिक्चर को पेंच करने के लिए स्ट्रिंग नहीं करना चाहिए?

उत्तर

4

जैसा कि ग्रेग के उत्तर और टिप्पणियों में बताया गया है, दो अलग-अलग सरणी प्रकार (क्योंकि स्ट्रिंग अक्षर क्या हैं) समस्या है। आप जेनेरिक प्रकारों के लिए फ़ंक्शन को छोड़ना चाहते हैं, लेकिन इसे चरित्र पॉइंटर्स और सरणी के लिए अधिभारित करना चाहते हैं, यह अधिकतर उपयोगी होता है जब आप उन्हें थोड़ा अलग तरीके से व्यवहार करना चाहते हैं।

void compare(char const* a, char const* b) { 
    // do something, possibly use strlen() 
} 

template<int N1, int N2> 
void compare(char const (&a)[N1], char const (&b)[N2]) { 
    // ... 
} 

आपको लगता है कि तुलना चरित्र संकेत स्पष्ट रूप से लेना चाहिए निर्दिष्ट करने के लिए चाहते हैं, तो सरणियों स्वचालित रूप से परिवर्तित कर देंगे:

compare<char const*>("aa", "bbbb"); 

दूसरी ओर, शायद तुलना दो अलग अलग प्रकार के साथ काम करने लिखा जा सकता है ? यह अन्य प्रकारों के लिए उपयोगी भी हो सकता है, उदा। शायद यह f(a) पर कॉल करता है यदि a.size() < b.size(), और f(b) अन्यथा (f ओवरलोडेड के साथ)। (T1 और टी 2 एक ही प्रकार के नीचे रहने की अनुमति है, और इस रूप में ऊपर दो यह अधिक भार के बजाय अपने समारोह की जगह लेंगे।)

template<typename T1, typename T2> 
void compare(T1 const& a, T2 const& b) { 
    // ... 
} 
6

आपका उदाहरण संकलित अगर आप घोषणा करने के लिए बदलने के लिए:

void compare(const T* a, const T* b) 

कारण है कि अलग अलग आकार के किरदार सरणियों के प्रकार वास्तव में विभिन्न प्रकार हैं। यदि आपने टेम्पलेट फ़ंक्शन के भीतर sizeof(T) का उपयोग किया है तो संकलक को अस्पष्टता को हल करने का तरीका नहीं पता होगा। उपर्युक्त घोषणा के साथ, आप टेम्पलेट फ़ंक्शन को पॉइंटर-टू-टी प्रकारों के साथ बुला रहे हैं, जो संकलक पारित होने पर संकलक const char* के रूप में खुशी से हल करेंगे।

+0

@Greg, वर्तमान घोषणा के साथ समस्या क्या है? – chappar

+0

लिखित रूप में आपकी घोषणा की आवश्यकता है कि फ़ंक्शन तुलना दो पैरामीटर लेती है जो बिल्कुल वही प्रकार हैं। "कॉन्स चार [3]" और "कॉन्स चार [5]" एक ही प्रकार के नहीं हैं। –

+0

आपके मौजूदा कोड में, "तुलना" शून्य तुलना की तरह कुछ मूल्यांकन करेगा (char a [2], char b [4])। संदर्भों के बजाय पॉइंटर्स का उपयोग करना मतलब है कि टी को दो अलग-अलग आकार के सरणी (जो विभिन्न प्रकार हैं) के बजाय सुरक्षित रूप से "चार" का मूल्यांकन किया जा सकता है। – Justicle

3

कंपाइलर स्ट्रिंग अक्षर को वर्ण बफर के रूप में समझना पसंद करेगा यदि यह कर सकता है। यदि नहीं, तो यह उन्हें कॉन्स्ट चार * के रूप में व्याख्या कर सकता है। हालांकि, संकलक टी की सर्वोत्तम व्याख्या को खोजने का प्रयास करने के लिए कोई बैकट्रैकिंग नहीं करेगा। यह जटिल नहीं है। एक बार यह फैसला करता है कि टी एक कॉन्स चार [3] है, यह आगे बढ़ता है। दूसरे तर्क का मूल्यांकन करना विफल रहता है।

आप

compare(static_cast<const char *>("aa"),static_cast<const char *>("bbbb")); 

से कॉल करने की यदि आप के लिए तैयार हैं।

+0

लेकिन यह नरक की तरह पढ़ता है :) – xtofl

+0

("aa", "bbbb") की तुलना करें, और टेम्पलेट्स + अधिभार रिज़ॉल्यूशन लगभग इतना आसान नहीं है :( –

+0

टेम्पलेट ओवरलोड रिज़ॉल्यूशन सरल नहीं है, लेकिन यह नहीं है टी के लिए एक प्रकार का अनुमान लगाने के लिए काफी जटिल है जो यहां दोनों चर को एकीकृत करता है, भले ही आप एक कार्यान्वयन की कल्पना कर सकें। –

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