2012-02-02 17 views
17

मैं आज सुबह कुछ टेम्पलेट कोड पर काम कर रहा था, जहां मैंने BOOST_STATIC_ASSERT का उपयोग किया ताकि यह सुनिश्चित किया जा सके कि मैं गलत प्रकार का संदर्भ नहीं बना रहा था, क्योंकि मैंने सोचा था कि यह एक स्पष्ट त्रुटि संदेश हो सकता है।सी ++ कैसे एक कॉन्स डबल संभालता है और जो एक int को संदर्भित करता है?

#include <iostream> 

int main() 
{ 
    int x = 5; 
    const double& y = x; 
    std::cout << y << std::endl; 

    return 0; 
} 

: हालांकि जब मैं स्थिर ज़ोर को हटाने के विकल्प संकलक त्रुटि मुझे लगता है कि जीसीसी की खोज के लिए भी शिकायत नहीं है जब आप एक स्थिरांक डबल & किसी पूर्णांक की चर्चा करते हुए बनाने की कोशिश चौंक गया था पर एक नज़र लेने की कोशिश की संकलित करता है, और यह भी चेतावनी नहीं देता है:

$ g++ ~/stuff/badRef.cpp -Wall -Wextra -pedantic 
$ a.out 
5 

यहां क्या हो रहा है? क्या यह अपरिभाषित व्यवहार है? यदि ऐसा है तो शिकायत क्यों नहीं करती? मेरी मशीन int पर 4 बाइट्स और एक डबल 8 है। इसका मतलब है कि एक डबल & प्रिंट करते समय इसे उस पते पर 8 बाइट्स को डबल के रूप में समझना चाहिए और प्रिंट करना चाहिए, फिर भी उस स्थान पर वास्तव में 4 बाइट int है।

बहुत उलझन में। मदद!

+0

जीसीसी का कौन सा संस्करण? –

+0

यह संस्करण 4.3.3 है। – voltrevo

+0

क्या होता है जब आप 'x = 42; 'को' डबल और y = x; 'के बाद जोड़ते हैं? यह पहली नजर में उत्सुक/अप्रत्याशित हो सकता है। – moala

उत्तर

22

const double& y = x;static_cast<double>(x) मूल्य के साथ एक अस्थायी double बनाता है, तो उस अस्थायी को y पर अस्थायी बनाता है। अस्थायी जीवनकाल y के जीवनकाल से मेल खाने के लिए बढ़ाया गया है।

यह पूरी तरह से कानूनी सी ++ (03 और 11) है, इसलिए चेतावनी/त्रुटि की कमी है।

+0

बहुत बढ़िया। जब आप एक्स बढ़ाते हैं तो क्या होता है, इसके बाद मैंने वास्तव में आपके जवाब से पहले यह पता लगाया, फिर y प्रिंट करें। यह नहीं बदला इसलिए मैंने सोचा - "ज़ाहिर है! यह एक अस्थायी से बांधता है!"। साथ ही, gcc इसे -std = C++ 98 के साथ स्वीकार करता है, इसलिए मैं अनुमान लगा रहा हूं कि यह वैध C++ 98 भी है? – voltrevo

+0

@ मोज़ाज़ा 314: "* मैं अनुमान लगा रहा हूं कि यह वैध सी ++ 98 भी है? *" हां; मेरे पास उस विशेष मानक की एक प्रति हाथ नहीं है, लेकिन मैं काफी हद तक निश्चित हूं कि सी ++ 03 में जो चीजें शामिल की गईं उनमें से एक नहीं है।ध्यान रखें, हालांकि, '-std = C++ 98' वास्तव में सी ++ 03 नियम लागू करता है, सी ++ 98 नियम नहीं, तर्क नाम नहीं है। – ildjarn

+0

मुझे यह नहीं मिला ... आप कभी भी 'कॉन्स्ट डबल' के बजाय अस्थायी रूप से बाध्य करते समय 'डबल और' क्यों करेंगे? – Mehrdad

2

const T& एक अस्थायी करने के लिए बाध्य कर सकते हैं, तो xdouble करने के लिए परिवर्तित किया जा रहा है और प्रति y के लिए बाध्य है। यदि आप चेक करते हैं, तो आप देखेंगे कि &x != &y। इस व्यवहार का कारण है उत्तीर्ण करने वाले अक्षरों को उन कार्यों के लिए अनुमति देना जो उनके पैरामीटर const संदर्भ से लेते हैं।

+0

ठीक है, "कॉपी संग्रहित नहीं है", 'y' रूपांतरण से उत्पन्न अस्थायी से बांधता है, क्योंकि यह एक कॉन्स्ट्लू संदर्भ है। –

+0

@ कैटप्लसप्लस: "बाध्य" से अच्छी तरह से "संग्रहीत" में बदल दिया गया है, अगर स्पष्ट नहीं किया गया है, तो कम से कम पेडेंटिक रूप से सही होना चाहिए। : पी –

11

यह अच्छी तरह से परिभाषित और कानूनी है। y एक अस्थायी को संदर्भित करता है। यह भी विचार है जब आप पैरामीटर भेजने:

void foo(const int& p); 
foo(3.14); 

भी है कि इस वैध सी ++ अगर संदर्भ const नहीं है नहीं है ध्यान दें। वीएस 6 ने यह गलत पाया और अस्थायी संदर्भ के लिए एक अस्थायी संदर्भ बाध्यकारी की अनुमति दी। यह केवल कॉन्स संदर्भों पर लागू होता है।

1

यह उन लोगों के लिए एक अच्छा उदाहरण है जो सोचते हैं कि पॉइंटर्स और संदर्भ समान हैं।

double const*const y2 = &x; 

gives 
bad.cpp:7:30: error: cannot convert ‘int*’ to ‘const double* const’ in initialization 

संदर्भों के लिए काम करने का कारण अन्य पदों में समझाया गया है।

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