कई मामलों में जब किसी फ़ंक्शन से स्थानीय लौटाते हैं, तो आरवीओ अंदर आ जाता है। हालांकि, मैंने सोचा कि स्पष्ट रूप से std::move
का उपयोग करके आरवीओ नहीं होने पर कम से कम लागू हो जाएगा, लेकिन जब भी संभव हो तो आरवीओ लागू होता है। हालांकि, ऐसा लगता है कि यह मामला नहीं है।std :: move आरवीओ को क्यों रोकता है?
#include "iostream"
class HeavyWeight
{
public:
HeavyWeight()
{
std::cout << "ctor" << std::endl;
}
HeavyWeight(const HeavyWeight& other)
{
std::cout << "copy" << std::endl;
}
HeavyWeight(HeavyWeight&& other)
{
std::cout << "move" << std::endl;
}
};
HeavyWeight MakeHeavy()
{
HeavyWeight heavy;
return heavy;
}
int main()
{
auto heavy = MakeHeavy();
return 0;
}
मैं कुलपति ++ 11 और जीसीसी 4.71, डिबग और रिलीज (-O2
) config के साथ इस कोड का परीक्षण किया। प्रतिलिपि ctor कभी नहीं कहा जाता है। चाल ctor केवल डीबीयूजी विन्यास में वीसी ++ 11 द्वारा बुलाया जाता है। दरअसल, विशेष रूप से इन कंपाइलरों के साथ सब कुछ ठीक लगता है, लेकिन मेरे ज्ञान के लिए, आरवीओ वैकल्पिक है।
हालांकि, अगर मैं स्पष्ट रूप से move
का उपयोग करें:
HeavyWeight MakeHeavy()
{
HeavyWeight heavy;
return std::move(heavy);
}
कदम ctor हमेशा कहा जाता है। तो इसे "सुरक्षित" बनाने की कोशिश करना इससे भी बदतर हो जाता है।
मेरे प्रश्न हैं:
- std::move
क्यों आरवीओ को रोकता है?
- "सर्वश्रेष्ठ के लिए आशा" और आरवीओ पर भरोसा करने के लिए बेहतर कब होता है, और मुझे स्पष्ट रूप से std::move
का उपयोग कब करना चाहिए? या, दूसरे शब्दों में, मैं संकलक अनुकूलन को अपना काम कैसे कर सकता हूं और आरवीओ लागू नहीं होने पर अभी भी कदम लागू कर सकता हूं?
लोग अभी भी "सर्वश्रेष्ठ के लिए आशा" के बारे में क्यों बात करते हैं? वे किस प्रकार का कंपाइलर उपयोग कर रहे हैं जिसमें सी ++ 11 समर्थन है लेकिन आरवीओ ठीक से नहीं हो सकता है? –
प्रतिलिपि कॉपी करें (आरवीओ के पीछे तंत्र) केवल कुछ निश्चित, सख्त स्थितियों के तहत अनुमति है। 'Std :: move' लिखना उन शर्तों को पूरा होने से रोकता है। –
@KerrekSB और std :: move द्वारा रोके गए इन स्थितियां हैं ...? – cdoubleplusgood