2013-06-18 6 views
5

एएस 3 के वर्षों के बाद, मैं सी ++ जारी करने की कोशिश कर रहा हूं। संदर्भ अभी भी मुझे फिट कर रहे हैं।फ़ंक्शन का परिणाम संदर्भ के रूप में पारित नहीं किया जा सकता

निम्नलिखित कार्यों पर विचार करें:

#include <cstdio> 
#include <list> 

void f(std::list<int>& v) { 
    for (std::list<int>::iterator i = v.begin(); i != v.end(); ++i) 
    printf("Hello %d\n", *i); 
} 

std::list<int> get(void) { 
    std::list<int> list; 
    list.push_back(0); 
    return list; 
} 

अब, कर निम्नलिखित:

std::list<int> l = get(); 
f(l); 

ठीक है, लेकिन f(get()) निम्नलिखित त्रुटि उत्पन्न करेगा:

"no matching function for call to 'f'", "candidate function not viable: no known conversion from `'std::list<int>' to 'std::list<int>&' for 1st argument"

क्यों कि है ? क्या ऐसा इसलिए है क्योंकि फ़ंक्शन का परिणाम अदृश्य रूप से const है?

+0

एक बार जब मैं क्लैंग के लिए जीसीसी के त्रुटि संदेश को पसंद करता हूं: 'त्रुटि: प्रकार 'std :: list > और' अस्थायी प्रकार से 'std के गैर-कॉन्स्ट संदर्भ का अमान्य प्रारंभिकरण: : सूची > '' –

उत्तर

8

जब आप ऐसा करते:

f(get()); 

आप एक अस्थायी std::list<int>f() लिए गुजरती हैं। अस्थायी एक गैर-कॉन्स्ट संदर्भ से बंधे नहीं जा सकते हैं। तो आप const संदर्भ पास करके इसे ठीक कर सकते हैं, क्योंकि आप तर्क को संशोधित नहीं करना चाहते हैं।

void f(const std::list<int>& v) 
{ // ^^^^^ 
    for (std::list<int>::const_iterator i = v.begin(); i != v.end(); ++i) 
    { //     ^^^^^^^^^^^^^^ 
    printf("Hello %d\n", *i); 
    } 
} 

नोट यह जरूरी है कि है कि आप एक const_iterator उपयोग करते हैं, std::list::begin() const और इसी end() विधि वापसी const_iterator रों के बाद से। सी ++ 11 में आप

for (auto i = v.begin(); i != v.end(); ++i) 
    ... 

या यहाँ तक कि

for (const auto& i : v) 
    std::cout << i << "\n"; 
+1

कुंजी शब्द: अस्थायी –

+0

+1 स्पष्ट उत्तर –

-1

ऐसा इसलिए है क्योंकि अपने तर्क टी & है करने के लिए इस आसान बनाने में कर सकते हैं। यह टी cont & था, यह ठीक काम किया।

कुछ पुराने कंपाइलर्स ने आपके संस्करण को एक्सटेंशन के रूप में काम किया - नियम कुछ मनमाने ढंग से है, और आश्चर्य से बचने के लिए है। टी & तर्क का मतलब आउट (या INOUT) प्रकार है, और यदि अस्थायी रूप में संशोधन समाप्त हो जाता है, तो यह आश्चर्य की बात है।

+0

के लिए +1 और समस्या यह है? –

0

आप get() विधि से अस्थायी std::list चर लौट रहे हैं। यह काम नहीं करता है क्योंकि कार्य करने के लिए आपका तर्क const नहीं है।

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

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