2014-04-14 7 views
11

this question से प्रेरित होकर, मैं निम्नलिखित कोड की कोशिश की। लेकिन सी ++ 03 विनिर्देश खंड 12.2 ("अस्थायी") और सेक्शन 5.12 ("सशर्त ऑपरेटर") को ध्यान से पढ़ने के बाद, मुझे यकीन है कि यह काम करने की गारंटी है या नहीं।सशर्त ऑपरेटर + Upcast + स्थिरांक संदर्भ

तो, यह मान्य कोड है, या यह अपरिभाषित व्यवहार का आह्वान करता है? क्या उत्तर सी ++ 03 और सी ++ 11 के लिए भिन्न है?

प्रासंगिक विनिर्देशों के उद्धरणों की सराहना की जाएगी।

+0

http://stackoverflow.com/questions/14405837/lifetime-extension-and-the-conditional-operator –

+1

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects .html # 86 –

+0

मेरे लिए बिल्कुल ठीक लग रहा है ... क्या, विशेष रूप से, आपकी चिंता है? – ildjarn

उत्तर

6

ओह, यह बहुत अमान्य है।

पर विचार करें:

#include <iostream> 
using namespace std; 

struct A { 
    virtual ~A() { cout << "~A" << endl; } 
    virtual void doit() const = 0; 
}; 

struct B : public A 
{ 
    ~B() override { cout << "~B" << endl; } 
    void doit() const override { cout << "A::doit" << endl; } 
}; 

struct C : public A 
{ 
    ~C() override { cout << "~C" << endl; } 
    virtual void doit() const { cout << "C::doit" << endl; } 
}; 

void foo(bool p) 
{ 
    cout << "foo(" << p << ")" << endl; 
    const A &a = (p ? static_cast<const A &>(B()) : static_cast<const A &>(C())); 
    a.doit(); 
} 

auto main(int argc, char* argv[]) -> int 
{ 
    cout << boolalpha; 

    foo(true); 
    cout << endl; 
    foo(false); 
} 

Coliru Viewer में आउटपुट, जी ++ 4.8 का उपयोग कर:

 
foo(true) 

~B 

~A 

pure virtual method called 

terminate called without an active exception 

bash: line 7: 16922 Aborted     (core dumped) ./a.out 

यह यूबी इसलिए किसी भी स्पष्टीकरण सच हो सकता है, लेकिन एक हद सुनिश्चित हो सकता है, विधानसभा की ओर देखे बिना, यह होता है कि:

  • एक अस्थायी बनाया गया है।
  • यह संदर्भ के लिए बाध्य है।
    यह एक संदर्भ के संदर्भ में एक संदर्भ है, इसलिए इसमें एक नए अस्थायी या टुकड़े का निर्माण शामिल नहीं है।
  • अस्थायी नष्ट हो गया है।
  • इसके भाग के रूप में इसके गतिशील प्रकार (vtable सूचक) को A में बदल दिया गया है, जो सार है।
  • A में शुद्ध आभासी कहा जाता है।
+0

ओह, अपूर्ण कोड के लिए खेद है, मैं देखता हूं कि मैंने घोषणाओं को हर जगह 'ओवरराइड' में बदलने का प्रबंधन नहीं किया है। और मानक स्तर पर, यह नॉर्वे में रात है, और कुछ घंटों में उठने से पहले मुझे कुछ आराम चाहिए। Howevever, शायद कुछ स्पष्टीकरण नोट के साथ जवाब बढ़ाया जाना चाहिए कि सवाल * जीवनकाल विस्तार नहीं है। –

+0

चर्चा में जाने के बिना सवाल में कितना भयानक कोड है, क्यों कॉन्स्ट संदर्भ के लिए अस्थायी नहीं है? क्या यह दायरे के अंत तक जीवनकाल का विस्तार नहीं करना चाहिए? मुझे लगता है कि यही उम्मीद है ओपी। –

+1

@ BЈовић: जैसा कि प्रश्नों में डीईपी द्वारा नोट किया गया है, आईएसई से संबंधित अभी तक एक अनसुलझा दोष रिपोर्ट है, ** [डीआर 1376] (http://www.open-std.org/JTC1/SC22/WG21/docs/ cwg_defects.html # 1376) **। समस्या यह है कि संदर्भ के लिए 'static_cast' का प्रभाव आविष्कारित" अस्थायी "ऑब्जेक्ट के संदर्भ में परिभाषित किया गया है। लेकिन यह सिर्फ एक शब्द की समस्या है। आजीवन विस्तार केवल अस्थायी के प्रत्यक्ष बाध्यकारी पर लागू होता है। किसी संदर्भ के संदर्भ में बाध्यकारी जीवनकाल का विस्तार नहीं करता है, अनिवार्य रूप से क्योंकि इसे ठीक से परिभाषित करना (उदा। फ़ंक्शन कॉल द्वारा उत्पादित संदर्भ को अस्वीकार करना) जटिल होगा। –

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