2010-03-17 20 views
23

मेरे पास एक ऐसा फ़ंक्शन है जो float** को तर्क के रूप में प्राप्त करता है, और मैंने इसे const float** लेने के लिए बदलने की कोशिश की।मुझे 'फ्लोट **' को 'कॉन्स्ट फ्लोट **' में परिवर्तित करने में त्रुटि क्यों मिल रही है?

संकलक (g++) यह पसंद नहीं था और जारी:

invalid conversion from ‘float**’ to ‘const float**’

यह मेरे लिए कोई मतलब नहीं है, मुझे पता है (और सत्यापित) है कि मैं एक समारोह है कि const char* लेता है char* पारित कर सकते हैं , तो const float** के साथ क्यों नहीं?

उत्तर

20

देखें Why am I getting an error converting a Foo** → const Foo**?

क्योंकि परिवर्तित Foo**const Foo** अवैध और खतरनाक होगा ... कारण Foo**const Foo** से रूपांतरण खतरनाक है कि यह आप चुपचाप जाने हैं और गलती से बिना एक स्थिरांक फू वस्तु को संशोधित है एक कास्ट

संदर्भ इस उदाहरण के लिए एक उदाहरण देता है कि इस तरह के एक अंतर्निहित रूपांतरण से मुझे const ऑब्जेक्ट को बिना किसी कलाकार के संशोधित करने की अनुमति मिल सकती है।

+3

शायद एक सारांश आपके उत्तर में अधिक जोड़ देगा। – GManNickG

18

यह एक बहुत ही मुश्किल प्रतिबंध है। यह भाषा के एलियासिंग नियमों से संबंधित है। , मानकों क्या कहते हैं पर एक नजर डालें क्योंकि मैं इस सामना करना पड़ा है एक बार पहले:

(61 पृष्ठ)

[ध्यान दें: एक कार्यक्रम एक सूचक के लिए प्रकार टी के एक सूचक ** आवंटित कर सकते हैं यदि टाइप कॉन्स टी ** (यानी, यदि लाइन // 1 नीचे दी गई थी), एक प्रोग्राम अनजाने में एक कॉन्स्ट ऑब्जेक्ट (जैसा कि यह लाइन // 2 पर किया गया है) को संशोधित कर सकता है। उदाहरण,

int main() { 
    const char c = 'c'; 
    char* pc; 
    const char** pcc = &pc; //1: not allowed 
    *pcc = &c; 
    *pc = 'C'; //2: modifies a const object 
} 

अंत टिप्पणी] के लिए

8

आप const float** पैरामीटर परिवर्तित यदि आप तो एक const float* स्मृति स्थान जहां पैरामीटर अंक पर संग्रहीत कर सकती है। लेकिन कॉलिंग फ़ंक्शन सोचता है कि इस स्मृति स्थान में गैर-कॉन्स float* होना चाहिए और बाद में यह इंगित करने के लिए float को बदलने का प्रयास कर सकता है।

इसलिए आप float** को const float** पर नहीं डाल सकते हैं, यह आपको उन स्थानों पर पॉइंटर्स को स्थिरांक रखने की अनुमति देगा जहां पॉइंटर्स को परिवर्तनीय मानों की अपेक्षा की जाती है।

अधिक जानकारी के लिए C++ FAQ Lite देखें।

+0

+1 - सर्वोत्तम उत्तर। – JonH

10

अन्य एवरों ने निराश किया है क्यों यह सी ++ में एक त्रुटि है।

मुझे अपने प्रश्न के पीछे प्रश्न का समाधान करने दें। आप अपने फ़ंक्शन के इंटरफ़ेस में, यह कहना चाहते थे कि आपका फ़ंक्शन सरणी में निहित फ्लोट मानों को संशोधित नहीं करेगा। अच्छा इरादा, और यह सक्षम करता है कि आपके फ़ंक्शन को const float ** सरणी के साथ बुलाया जाता है। आपके प्रश्न के पीछे सवाल यह होगा कि बदसूरत जानवरों को हल किए बिना इसे कैसे प्राप्त किया जाए।

आप जो चाहते थे उसे हासिल करने का सही तरीका const float * const * पर अपने फ़ंक्शन पैरामीटर के प्रकार को बदलना है।

सितारों के बीच अतिरिक्त const संकलक को आश्वासन देता है कि आपकी विधि सरणी में फ्लोट करने के लिए पॉइंटर्स को स्टोर करने की कोशिश नहीं करेगी, क्योंकि इस प्रकार की घोषणा करता है कि पॉइंटर मान भी स्थिर हैं।

अब आप इस फ़ंक्शन को float ** (जो आपके प्रश्न में उदाहरण था), const float **, और const float * const * तर्कों के साथ कॉल कर सकते हैं।

+0

हां। कॉन्स सिंटैक्स के लिए नियम यह है कि यदि यह किसी प्रकार के बायीं तरफ है, तो यह चीज को इसके दाहिने ओर कसकर बांधता है, अन्यथा यह चीज़ को इसके बाईं ओर संशोधित करता है। तो 'const int 'और' int const' एक ही प्रकार के होते हैं, 'const int *' और' int const * 'दोनों बिंदुओं को 'int' पर इंगित करते हैं, 'int * const' एक सूचक है जिसे आप नहीं कर सकते एक 'int' में बदलें, और 'const int * const' और' int const * const' पॉइंटर्स हैं जिन्हें आप 'int' में बदल नहीं सकते हैं, आप बदल नहीं सकते हैं। अनिश्चित काल तक बढ़ाएं। – Ben

+0

"जो आप चाहते थे उसे हासिल करने का सही तरीका है अपने फंक्शन पैरामीटर के प्रकार को कॉन्स फ्लोट * कॉन्स * में बदलना।" वास्तव में जो मैं खोज रहा था, यह जवाब अधिक होना चाहिए। –

+0

क्या होगा अगर मैं हस्ताक्षर 'foo (const char ** bar)' के साथ एक एपीआई कॉल कर रहा हूं? मेरे पास एपीआई पर कोई नियंत्रण नहीं है, मैं फ़ंक्शन कॉल में इस त्रुटि को कैसे हल कर सकता हूं? –

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