2017-12-18 50 views
9

के लिए में क्यों इस कोड काम मैं चाहिए के रूप में नहीं है?पुनरावृत्ति, कि वेक्टर होता है, सीमा पाश

for (auto it: *std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5}))) 
    std::cout << it << std::endl; 

वेक्टर वस्तु पाश की पहली यात्रा निष्पादित करने से पहले नष्ट हो जाता है

+1

ध्यान दें कि सी ++ 20 को यहां बताए गए के माध्यम से "प्रारंभकर्ता साथ बयानों के लिए रेंज के आधार पर" ख़तरा की इस तरह से बचने के लिए अनुमति देता है: https://herbsutter.com/2017/11/11/ यात्रा-रिपोर्ट-फॉल-इसो-सी मानकों पर बैठक-अल्बुकर्क /। यही है: आप 'लूप' को अलग-अलग लूप के लिए जीवन सुनिश्चित करने के लिए अलग-अलग घोषित करते हैं, फिर इसे फिर से करने के लिए रेंज के रूप में उपयोग करें। –

+1

क्यों न केवल लिखें (ऑटो इसे: {1, 2, 3, 4, 5}) '? और अधिक जटिल मामलों के लिए, क्यों 'std :: unique_ptr >' 'std :: वेक्टर ' के बजाय हो रही है। – Jarod42

+0

हां, यह एक बहुत ही संकलित उदाहरण है, जो समस्या क्षेत्र को प्रदर्शित करता है लेकिन एक अतिरंजित तरीके से। :) –

उत्तर

11

range-based for loop के बराबर है:

{ 
    init-statement 
    auto && __range = range_expression ; 
    ... 
} 

अपने range_expression के लिए, यह होगा

auto && __range = *std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5})); 

लेकिन

तो range_expression एक अस्थायी देता है, अपने जीवनकाल पाश के अंत तक, के रूप में rvalue संदर्भ __range के लिए बाध्य ने संकेत बढ़ाया है, लेकिन सावधान रहना है कि किसी भी अस्थायी के जीवनकाल range_expression भीतर लागू नहीं होता है।

क्या std::make_unique रिटर्न पूर्ण अभिव्यक्ति यह नष्ट हो जाएगा के बाद एक अस्थायी std::unique_ptr है। इसका मतलब है कि std::vector इसके द्वारा प्रबंधित भी नष्ट हो जाएगा; भले ही std::vector अस्थायी std::unique_ptr से मिला अग्रेषण संदर्भ के लिए बाध्य है, अपने जीवनकाल बढ़ाया नहीं किया जाएगा।

से सी ++ 20 आप init-कथन का उपयोग आसपास काम कर सकते हैं; जैसे

for (auto p = std::make_unique<std::vector<int>>(std::vector<int>({1, 2, 3, 4, 5})); auto it : *p) 
    std::cout << it << std::endl; 
+1

कि पेज से: "तो' range_expression' एक अस्थायी देता है, अपने जीवनकाल के रूप में rvalue संदर्भ '__range' के लिए बाध्य ने संकेत दिया, पाश के अंत तक बढ़ा दिया है, लेकिन सावधान रहना किसी भी अस्थायी के जीवनकाल' range_expression भीतर है कि है 'विस्तारित नहीं है।" – 0x5453

+0

चिपचिपा वाक्यविन्यास चीनी है, धन्यवाद – Daniil

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