2011-01-12 47 views
16

इस त्रुटि संदेश का क्या अर्थ है?ओवरलोडेड फ़ंक्शन का कॉल संदिग्ध है

error: call of overloaded ‘setval(int)’ is ambiguous 
huge.cpp:18: note: candidates are: void huge::setval(unsigned int) 
huge.cpp:28: note:     void huge::setval(const char*) 

मेरे कोड इस तरह दिखता है:

#include <iostream> 
#define BYTES 8 
using namespace std ; 

class huge { 
private: 
    unsigned char data[BYTES]; 
public: 
    void setval(unsigned int); 
    void setval(const char *); 
}; 

void huge::setval(unsigned int t) { 
    for(int i = 0; i< BYTES ; i++) { 
     data[i] = t; 
     t = t >> 1; 
    } 
} 

void huge::setval(const char *s) { 
    for(int i = 0; i< BYTES ; i++) 
     data[i] = s[i]; 
} 

int main() { 
    huge p; 
    p.setval(0); 
    return 0; 
} 
+4

मुझे लगता है कि इस प्रश्न का उत्तर इस बात पर निर्भर करेगा कि आप किस फ़ंक्शन को कॉल करने का प्रयास कर रहे हैं। मैं मान सकता हूं, लेकिन स्पष्ट रूप से मैं तब तक सुनिश्चित नहीं हो सकता जब तक कि आप मुझे नहीं बताते। क्या मैं संकलक के साथ काम करता हूं मुझे आश्चर्य है ... –

+0

@ कोनराड रुडॉल्फ शाब्दिक '0' दोनों 'हस्ताक्षरित int' और' const char * 'के लिए मान्य मान है। –

+0

@RyanP हाँ, मुझे आमतौर पर पता है। मुझे नहीं पता कि मेरा मतलब क्या था। विशेष रूप से अंतिम पैराग्राफ के लिए –

उत्तर

17

शाब्दिक 0 का सी ++ में दो अर्थ हैं।
एक तरफ, यह मान 0 के साथ एक पूर्णांक है।
दूसरी ओर, यह एक शून्य-सूचक स्थिर है।

आपके setval फ़ंक्शन के रूप में या तो int या char* स्वीकार कर सकते हैं, संकलक यह तय नहीं कर सकता कि आप किस अधिभार का मतलब है।

सबसे आसान समाधान सिर्फ 0 सही प्रकार पर डालना है।
एक अन्य विकल्प सुनिश्चित करने के लिए int अधिभार पसंद किया जाता है उदाहरण के लिए, एक दूसरे को एक टेम्पलेट बनाने के द्वारा है:

class huge 
{ 
private: 
    unsigned char data[BYTES]; 
public: 
    void setval(unsigned int); 
    template <class T> void setval(const T *); // not implemented 
    template <> void setval(const char*); 
}; 
+0

इसके लायक होने के लिए, मुझे कक्षा घोषणा के बाहर विशेषज्ञता शामिल करना पड़ा। मूल रूप से 'टेम्पलेट <> शून्य विशाल :: सेटवल (कॉन्स char *); 'अपनी कक्षा घोषणा के ठीक नीचे शामिल करें। अगर मैंने नहीं किया, तो मुझे वर्ग के दायरे में टेम्पलेट को विशेषज्ञता देने के बारे में एक त्रुटि मिली। हालांकि बड़ी चाल, यह मेरे कुछ इंटरफेस के साथ पहले मुझे फेंक दिया है। – vmrob

+1

'0' का सी ++ में केवल एक अर्थ है। यह 'int' प्रकार का एक पूर्णांक अक्षर है। यदि ओपी में वास्तव में एक 'int' लेना अधिभार था और दूसरा 'char *' ले रहा था, तो ओवरलोड रिज़ॉल्यूशन सफल होगा और 'int' अधिभार को चुना जाएगा। हालांकि, ओपी पैरामीटर प्रकार के रूप में 'हस्ताक्षरित int' का उपयोग करता है। और उन दो रूपांतरणों, 'int' -> 'unsigned int' बनाम शून्य सूचक स्थिर ->' char * 'संदिग्ध हैं। – dyp

+0

@dyp: यदि '0' का केवल एक अर्थ है, तो यह विभिन्न प्रारंभिक प्रकारों के साथ दो संदिग्ध रूपांतरणों में कैसे शामिल हो सकता है? –

1

उपयोग

p.setval(static_cast<const char *>(0)); 

या

p.setval(static_cast<unsigned int>(0)); 

त्रुटि ने संकेत के रूप में, 0 के प्रकार int है। इसे आसानी से unsigned int या const char * पर आसानी से डाला जा सकता है। मैन्युअल रूप से कलाकार बनाकर, आप संकलक को बता रहे हैं कि आप जो अधिभार चाहते हैं।

1

कास्ट तो संकलक जानता मूल्य जो कॉल करने के लिए काम करते हैं:

p.setval(static_cast<const char *>(0)); 

ध्यान दें, कि आप अपने कोड में एक विभाजन गलती है के बाद आप इसे (निर्भर करता है संकलित करने के लिए मिलता है, जिस पर कार्य करते हैं क्या तुम सच में फोन करना चाहता था)।

3

निम्नलिखित के साथ p.setval(0); को प्रतिस्थापित करें।

const unsigned int param = 0; 
p.setval(param); 

इस तरह से यह सुनिश्चित करता है कि स्थिर 0 किस प्रकार है।

2

यह संदिग्ध है क्योंकि एक सूचक केवल एक पता है, इसलिए एक इंट को पॉइंटर - 0 (एक इंट) के रूप में भी माना जा सकता है जिसे बिना हस्ताक्षर किए गए int या char * में आसानी से परिवर्तित किया जा सकता है।

संक्षिप्त उत्तर p.setval() को किसी ऐसे चीज़ के साथ कॉल करना है जो अनजाने में से किसी एक प्रकार के लिए लागू किया गया है: हस्ताक्षरित int या char *। पी .setval (0 यू), पी .setval ((हस्ताक्षरित int) 0), और पी .setval ((char *) 0) सभी संकलित करेंगे।

आम तौर पर इस स्थिति से बाहर रहने के लिए एक अच्छा विचार है, हालांकि, इस तरह के समान प्रकार के अधिभारित कार्यों को परिभाषित नहीं करना।

+0

+1। –

+0

सी ++ 0x के लिए इंतजार नहीं कर सकता, जब हमारे पास अंत में nullptr कीवर्ड होगा :) –

+0

p.setval ((char *) 0) संकलित होगा, लेकिन एप्लिकेशन क्रैश हो जाएगा। p.setval (0U) ठीक काम करता है – Rajesh

12

समाधान बहुत आसान है अगर हम निरंतर मूल्य के प्रकार, जो अहस्ताक्षरित होना चाहिए "पर विचार int "के बजाय int"।

setval(0) 

उपयोग::

बजाय

setval(0u) 

प्रत्यय "यू" संकलक बता यह एक अहस्ताक्षरित पूर्णांक है। फिर, कोई रूपांतरण की आवश्यकता नहीं होगी, और कॉल स्पष्ट होगा।

+1

संकलक को बताने के लिए सबसे अच्छा जवाब, सरल और सुरुचिपूर्ण तरीका –

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