2016-12-03 16 views
7

मान लें कि हम इस स्थितिक्या आरवीओ इस स्थिति पर लागू है?

std::string v_1() 
{ 
    return "name"; 
} 
std::string test = v_1(); 

RVO यहां लागू किया है है? मुझे लगता है कि उत्तर नहीं है, क्योंकि आरवीओ को लागू करने के नियम एक हैं: "यदि कोई फ़ंक्शन किसी वर्ग प्रकार को मान द्वारा देता है, और वापसी कथन की अभिव्यक्ति स्वचालित भंडारण अवधि के साथ एक गैर-अस्थिर वस्तु का नाम है, जो नहीं है फ़ंक्शन पैरामीटर, या कैच क्लॉज पैरामीटर, और जिसमें फ़ंक्शन के रिटर्न प्रकार के रूप में एक ही प्रकार (शीर्ष-स्तर सीवी-योग्यता को अनदेखा करना) है, फिर प्रतिलिपि/स्थान छोड़ा गया है " और इस स्थिति में लौटाई गई वस्तु में फ़ंक्शन के रिटर्न प्रकार का एक ही प्रकार नहीं है, लेकिन मैं 100% नहीं हूं कि आरवीओ यहां लागू नहीं है।

बहुत बहुत धन्यवाद।

पीएस। इस बात पर https://www.youtube.com/watch?v=AKtHxKJRwp4 (मिनट 40, दूसरा 18) माइक्रोसॉफ्ट से स्टीफन, ऐसी परिस्थिति के बारे में बात करता है जहां आरवीओ लागू नहीं किया जा सकता है क्योंकि फ़ंक्शन का रिटर्न प्रकार लौटा हुआ ऑब्जेक्ट के प्रकार से अलग होता है (उसके उदाहरण में एक युगल बनाम एक जोड़ी)। मुझे लगता है कि वही सिद्धांत यहां लागू होता है।

+3

यह ज्यादातर 'वापसी std :: string (" name ")' – Jarod42

+0

वापस लौटाया जाता है * नहीं * 'const *' const * ' – user268396

+0

@ user268396 आप सही हैं लेकिन अधिकांश में मामले (यहां भी) यह स्ट्रिंग में कनवर्ट करने से पहले एक में परिवर्तित हो गया है ... :) –

उत्तर

5

मुझे लगता है कि आप NRVORVO के साथ भ्रमित कर रहे हैं।

  • NRVO - नाम वापसी मान अनुकूलन
  • RVO - (बेनाम) वापसी मान अनुकूलन

NRVO एक नामित चर शामिल है जबकि RVO अनाम temporaries कि return बयान में निर्माण कर रहे हैं शामिल है।

वीडियो पर उदाहरण NRVO जहां वस्तु स्पष्ट रूप से नामित फोन करने वाले ढेर वहाँ समारोह के ढेर और एक अन्य में एक प्रकार से एक वस्तु का अस्तित्व है, क्योंकि जब प्रकार अलग हैं पर निर्माण नहीं किया जा सकता है कॉलर के ढेर पर दूसरे प्रकार की वस्तु।

आपका उदाहरण RVO है जहां आप पूर्व-निर्मित नामित वस्तु का उपयोग नहीं कर रहे हैं। आपके कोड में आप अस्थायी ऑब्जेक्ट को रिटर्न मान के रूप में बना रहे हैं। क्योंकि यह अस्थायी है जिसे आपने उद्धृत किया है, वह लागू नहीं होता है।

C++11 मानक के अनुसार मैं कोई कारण नहीं क्यों RVO नहीं हो सकता है देखते हैं:

12,8 कॉपी करने और आगे बढ़ वर्ग वस्तुओं [ class.copy ] ... ...

- जब एक अस्थायी वर्ग वस्तु जो बाउंस नहीं है डी संदर्भ में (12।2) कॉपी किया जाएगा/एक ही सीवी-अयोग्य प्रकार के साथ एक वर्ग वस्तु को ले जाया गया, कॉपी/कदम आपरेशन अस्थायी वस्तु छोड़े गए प्रतिलिपि का लक्ष्य में सीधे निर्माण करके छोड़ा जा सकता है/ले जाने के

char array लौटने से एक अस्थायी std::string बनाया गया है और है कि कॉलर पर वापस लौटाया जाता है।

3

एनआरवीओ और आरवीओ एलिशन के विभिन्न मामले हैं।

एलिशन वह जगह है जहां कई ऑब्जेक्ट्स का जीवनकाल एक ऑब्जेक्ट में विलय कर दिया जाता है।

नाम एनआरवीओ और आरवीओ नाम हैं जब मानक अनुमति देता है जब संकलक elision करता है।

return लाइन पर अस्थायी रूप से बनाए गए अस्थायी के बीच आपके उदाहरण में एलिशन की अनुमति है, फ़ंक्शन का रिटर्न वैल्यू, और नामित वेरिएबल आप रिटर्न वैल्यू को स्टोर करते हैं। प्रत्येक गंभीर कंपाइलर उन मानों को एक साथ जोड़ सकता है और तब तक जोड़ देगा, जब तक कि आप स्पष्ट रूप से यह संकलक झंडे के माध्यम से नहीं बताओ। और सी ++ में 17 उन elisions अनिवार्य होगा।

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