स्वीकृत उत्तर एक अच्छा जवाब है (और मैंने इसे ऊपर उठाया है)। लेकिन मैं थोड़ा और विस्तार में इस सवाल को संबोधित करना चाहता था:
मेरे सवाल की मूल है: क्यों यह कदम काम ऑपरेटर स्वचालित रूप से लेने नहीं करता है? संकलक जानता है कि वी असाइनमेंट के बाद उपयोग नहीं किया जाता है, है ना? या C++ 11 को संकलक को होने की आवश्यकता नहीं है जो स्मार्ट है?
इस संभावना चाल अर्थ विज्ञान के डिजाइन के दौरान देखा गया था।एक चरम पर, आप संकलक कुछ स्थिर विश्लेषण करते हैं और वस्तुओं से ले जाने के लिए जब भी संभव करने के लिए चाहते हो सकता है:
void set_name(std::string v)
{
name_ = v; // move from v if it can be proven that some_event is false?
if (some_event)
f(v);
}
अंततः संकलक से विश्लेषण के इस प्रकार की मांग बहुत मुश्किल है। कुछ कंपाइलर सबूत बनाने में सक्षम हो सकते हैं, और अन्य नहीं हो सकते हैं। इस प्रकार कोड का नेतृत्व करना जो वास्तव में पोर्टेबल नहीं है।
ठीक है, तो बयान के बिना कुछ सरल मामलों के बारे में क्या?
void foo()
{
X x;
Y y(x);
X x2 = x; // last use? move?
}
खैर, यह अगर y.~Y()
देखेंगे x
से ले जाया गया है पता करने के लिए मुश्किल है। और सामान्य रूप में:
void foo()
{
X x;
// ...
// lots of code here
// ...
X x2 = x; // last use? move?
}
यह संकलक इस विश्लेषण करने के लिए के लिए यदि x
सही मायने में नहीं रह गया है x2
के प्रति निर्माण के बाद प्रयोग किया जाता है पता करने के लिए मुश्किल है।
lvalues केवल परोक्ष मामलों में जहां नकल इलिजन पहले से ही अनुमति है में से ले जाया जा सकता है:
तो मूल "चाल" प्रस्ताव निहित चाल के लिए एक नियम है कि वास्तव में सरल है, और बहुत ही रूढ़िवादी था दे दी है।
उदाहरण के लिए:
#include <cassert>
struct X
{
int i_;
X() : i_(1) {}
~X() {i_ = 0;}
};
struct Y
{
X* x_;
Y() : x_(0) {}
~Y() {assert(x_ != 0); assert(x_->i_ != 0);}
};
X foo(bool some_test)
{
Y y;
X x;
if (some_test)
{
X x2;
return x2;
}
y.x_ = &x;
return x;
}
int main()
{
X x = foo(false);
}
यहाँ, सी ++ 98/03 नियमों से, इस कार्यक्रम या जोर नहीं हो सकता है, पर किया जाए या नहीं return x
पर इलिजन कॉपी होता है निर्भर करता है। यदि ऐसा होता है, तो प्रोग्राम ठीक चलता है। यदि ऐसा नहीं होता है, तो कार्यक्रम जोर देता है।
और इसलिए यह तर्क दिया गया था: जब आरवीओ की अनुमति है, हम पहले से ही ऐसे क्षेत्र में हैं जहां x
के मूल्य के संबंध में कोई गारंटी नहीं है। इसलिए हमें इस छूट का लाभ उठाने और x
से स्थानांतरित करने में सक्षम होना चाहिए। जोखिम छोटा दिखता था और लाभ विशाल देखा गया। न केवल इसका मतलब यह होगा कि कई मौजूदा कार्यक्रम एक सरल पुनर्मूल्यांकन के साथ बहुत तेज हो जाएंगे, लेकिन इसका मतलब यह भी था कि अब हम कारखाने के कार्यों से "केवल स्थानांतरित" प्रकार वापस कर सकते हैं। यह जोखिम अनुपात के लिए एक बहुत बड़ा लाभ है।
मानकीकरण की प्रक्रिया के अंत में हमने एक छोटे से लालची हो गया और यह भी कहा कि निहित कदम होता है जब एक से-value पैरामीटर लौट (और प्रकार वापसी प्रकार से मेल खाता है)। लाभ यहां अपेक्षाकृत बड़े लगते हैं, हालांकि कोड टूटने का मौका थोड़ा बड़ा है क्योंकि यह ऐसा कोई मामला नहीं है जहां आरवीओ (या है) कानूनी है। लेकिन मेरे पास इस मामले के लिए कोड तोड़ने का प्रदर्शन नहीं है।
तो अंत में, अपने मूल सवाल का जवाब है कि इस कदम अर्थ विज्ञान के मूल डिजाइन मौजूदा कोड को तोड़ने के संबंध में एक बहुत ही रूढ़िवादी मार्ग ले लिया है। अगर ऐसा नहीं होता, तो निश्चित रूप से इसे कमेटी में गोली मार दी जाएगी। इस प्रक्रिया में देर से, कुछ बदलाव हुए जिससे डिजाइन थोड़ा अधिक आक्रामक हो गया। लेकिन इस समय तक मूल प्रस्ताव बहुमत (लेकिन सर्वसम्मति से) समर्थन के साथ मानक में दृढ़ता से फैल गया था।
मुझे कहीं भी एक चालक कन्स्ट्रक्टर नहीं दिख रहा है? – Corbin
@ निकोलबोलस: यह इस प्रश्न से दूरस्थ रूप से संबंधित नहीं है। वह अपनी कक्षा के 'std :: string' सदस्य को स्थानांतरित करने के बारे में पूछ रहा है। वह कक्षा को स्थानांतरित करने की कोशिश नहीं कर रहा है। –
@MooingDuck: ओह। खैर, फिर कभी बुरा मत मानो। मैं वास्तव में करीबी वोट के बारे में बहुत कुछ नहीं कर सकता ... –