2012-03-22 24 views
23

संभव डुप्लिकेट:
Returning unique_ptr from functionsमुझे unique_ptr की प्रतिलिपि बनाने की अनुमति क्यों है?

20.7.1.2 [unique.ptr.single] परिभाषित करता है इस तरह निर्माता कॉपी:

// disable copy from lvalue 
unique_ptr(const unique_ptr&) = delete; 
unique_ptr& operator=(const unique_ptr&) = delete; 

तो, क्यों निम्नलिखित कोड compiles ठीक?

#include <memory> 
#include <iostream> 

std::unique_ptr<int> bar() 
{ 
    std::unique_ptr<int> p(new int(4)); 
    return p; 
} 

int main() 
{ 
    auto p = bar(); 

    std::cout<<*p<<std::endl; 
} 

मैं इसे इस तरह संकलित:

g++ -O3 -Wall -Wextra -pedantic -std=c++0x kel.cpp 

संकलक: जी ++ संस्करण 4.6.1 20,110,908 (रेड हैट 4.6.1-9)

+18

+1 वास्तव में हमें बता रहा है कि आप किस कंपाइलर का उपयोग कर रहे हैं और आपने कोड को कैसे संकलित किया है। StackOverflow पर एक दुर्लभ दृष्टि। –

+0

http://stackoverflow.com/questions/4316727/returning-unique-ptr-from-functions – Sjoerd

उत्तर

42

रिटर्न स्टेटमेंट में, यदि आप स्थानीय चर लौटाते हैं, तो अभिव्यक्ति को एक रैवल्यू के रूप में माना जाता है, और इस प्रकार स्वचालित रूप से स्थानांतरित हो जाता है। यह इस प्रकार है:

return std::move(p); 

यह unique_ptr(unique_ptr&&) कन्स्ट्रक्टर का आह्वान करता है।

मुख्य समारोह में, bar() एक अस्थायी उत्पन्न करता है, जो एक रैवल्यू है, और यह भी p में main में ठीक से स्थानांतरित हो गया है।

+0

नहीं, सबोबजेक्ट स्वचालित रूप से स्थानांतरित नहीं होते हैं। – Xeo

+0

12.8/31 मेरे प्रश्न में सटीक उदाहरण है। आप और नवाज दोनों सही हैं –

+0

@Xeo आप सही हैं। उस के बारे में कोई सवाल नहीं था? हाँ, http: // stackoverflow है।कॉम/प्रश्न/9183087/विल-सदस्य-सबोबजेक्ट्स-ऑफ-लोकल-वेरिएबल्स-बी-लेवल-भी-अगर-लौटे-ए-फंक्टी –

1

मुझे लगता है कि एक lvalue से है कि नकल है अक्षम, लेकिन "बार()" एक रैल्यू है इसलिए यह ठीक है। आपको निश्चित रूप से राजस्व से प्रतिलिपि बनाने में सक्षम होना चाहिए।

+3

और वास्तव में, यह प्रतिलिपि से चल रहा है, प्रतिलिपि नहीं है। – ulidtko

13

यह है नहींकी नकल की, यह ले जाया है।

वापसी कथन इस के बराबर है:

return std::move(p); 

pedantically तौर पर, कि शब्दार्थ बराबर है। हकीकत में, संकलक कोड को अनुकूलित कर सकता है, कॉल को कन्स्ट्रक्टर को कॉल कर रहा है। लेकिन यह केवल तभी संभव है जब आप इसे लिखते हैं:

return p; //It gives the compiler an opportunity to optimize this. 

यह अनुशंसित है।

return std::move(p); //No (or less) opportunity to optimize this. 

है नहीं सिफारिश की: हालांकि, संकलक अगर आप इस बारे में अनुकूलन करने के लिए कोई अवसर नहीं है। :-)

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

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