2017-02-10 7 views
33

से गुजरने के बाद lvalue संदर्भ अमान्य हो गया है क्या कोई यह बताएगा कि "पहचान" फ़ंक्शन, foo1 से गुजरने के बाद संदर्भ क्यों अमान्य हो गया? A पर "पता" नहीं है और foo1 द्वारा लौटाया गया है?पहचान फ़ंक्शन

struct A { 
    A(int x) : x_(x) {} 
    int x_; 
}; 

int main() { 

    function<const A&(const A& r)> foo1 = [](const A& r) { 
     return r; 
    }; 

    vector<A> vec{1, 2, 3}; 
    cout << foo1(vec[0]).x_ << endl; // RUNTIME ERROR 

    return 0; 
} 

समस्या लाइन में क्या अंतर से करता है:

const A& r = vec[0]; 
const A& r1 = r; 
+0

मैं vs2015 के साथ की कोशिश की और अपने कोड अच्छी तरह से काम करता है भी है। – alangab

+0

@alangab VS2013 में काम नहीं किया था। –

+8

मैंने सोचा था कि लैम्ब्डा को 'मूर्ख' कहा जाता था। वह मूर्ख था। –

उत्तर

43

समस्या आपका लैम्ब्डा है। यह ऐसा नहीं करता जो आपको लगता है कि यह करता है:

function<const A&(const A& r)> foo1 = [](const A& r) { 
//            ~~~~~~ 
    return r; 
}; 

ध्यान दें कि कोई पिछला रिटर्न प्रकार नहीं है। इसका मतलब है कि यह स्वचालित रूप से कम हो जाता है। कटौती आपको कभी संदर्भ प्रकार नहीं देती है, इसलिए यह लैम्ब्डा A देता है, A const& नहीं। वह अस्थायी A लौटाया गया है, फिर A const&function के operator() की वापसी के लिए बाध्य है। वह अस्थायी जीवनकाल-विस्तारित नहीं है। लेकिन जब हम foo1() पर कॉल करना समाप्त करते हैं, तो हमारे पास उस अस्थायी A का एक खतरनाक संदर्भ है। यह अपरिभाषित व्यवहार है, जो मुझे आपके कंपाइलर के साथ लगता है, आपको एक सहायक रनटाइम त्रुटि प्रदान करता है।

function<const A&(const A& r)> foo1 = [](const A& r) -> A const& { 
    return r; 
}; 

लेकिन फिर भी यह खतरनाक है, जब से तुम अभी भी एक अस्थायी इस समारोह में A गुजरती हैं और एक झूलने संदर्भ बाहर निकल सकते हैं:

इसे ठीक करने के आप स्पष्ट रूप से वापसी प्रकार निर्दिष्ट करने के लिए की जरूरत है। उस के आसपास कोई असली रास्ता नहीं है।


इस जाल में गिरने में आसानी LWG Issue 2813

+4

उह, यह एक बुरा जाल है :( –

+2

कम से कम कुछ प्रकार के रिटर्न प्रकार को बचाने के लिए '-> ऑटो &&' का उपयोग करने के लिए भी उपयोगी हो सकता है। – Predelnik

12

अपने function ऑब्जेक्ट जबकि const A& लैम्ब्डा आप इसे प्रदान नहीं करता है। यह रिटर्न स्टेटमेंट रिटर्न स्टेटमेंट से लिया जाता है, जिसे A माना जाता है। इसके बजाय एक स्पष्ट वापसी प्रकार जोड़ने का प्रयास करें।

function<const A&(const A& r)> foo1 = [](const A& r) -> const A& { 
    return r; 
}; 
संबंधित मुद्दे