2016-01-19 4 views
13

XValue की परिभाषा निम्नानुसार है:हमें व्यावहारिक रूप से 'स्पष्ट xvalues' की आवश्यकता कब होती है?

- एक XValue (एक "समाप्त हो रहा है" मूल्य) भी इतना है कि अपने संसाधनों से ले जाया जा सकता है आम तौर पर अपने जीवनकाल के अंत के पास, एक वस्तु को संदर्भित करता है (, उदाहरण के लिए)। एक xvalue कुछ प्रकार के अभिव्यक्तियों का परिणाम है जिसमें रावल संदर्भ (8.3.2) शामिल हैं। [उदाहरण: फ़ंक्शन को कॉल करने का नतीजा जिसका रिटर्न टाइप एक रावल्यू संदर्भ है, एक xvalue है। उदाहरण के लिए]

क्या हम कभी भी ऐसे फ़ंक्शन का उपयोग करने की आवश्यकता रखते हैं जहां वापसी का प्रकार एक रावल्यू संदर्भ है, जो एक xvalue है?

const int && Foo() 
{ 
    // ... 
} 

ले जाएं semantics एक पैरामीटर के रूप में एक रैल्यू संदर्भ ले, वापसी मूल्य नहीं। तो मुझे नहीं लगता कि यह मामला है।

+0

शीर्षक में "स्पष्ट" से आपका क्या मतलब है? –

+0

@ एम.एम. अगर मैं एक ऐसा फ़ंक्शन लिखता हूं जो एक xvalue देता है और मुझे इसके बारे में पता है, और यह मेरे द्वारा इरादा है, तो मैं कहूंगा कि यह स्पष्ट है कि xvalues ​​को इंगित करने के लिए कोई सिंथेटिक कीवर्ड नहीं है। –

उत्तर

4

रिटर्निंग रेवल्यू संदर्भ उन कार्यों के लिए उपयोग किए जा सकते हैं जो पैरामीटर के रूप में पहले ही रावल लेते हैं। एक साधारण उदाहरण:

struct X { 
    X() = default; 
    X(X&& other) { std::cout << "move ctor\n"; } 
    X(X const&) = delete; 
    void log(std::string const& s){ std::cout << "log: " << s << "\n"; } 
}; 

void sink(X&& x) { 
    x.log("sink"); 
} 

X&& passOn(X&& in) { 
    in.log("pass"); 
    return std::move(in); 
} 

X moveOn(X&& in) { 
    in.log("move"); 
    return std::move(in); 
} 

int main() { 
    sink(passOn(X())); 
    std::cout << "===============================\n"; 
    sink(moveOn(X())); 
} 

Live demo →

दूसरा समारोह, लौटे वस्तु बनाने के लिए कदम निर्माता फोन, जबकि पहला संदर्भ यह पहले से ही मिल गया पर पारित करेंगे होगा। यह अधिक उपयोगी है अगर हम मूल संदर्भ वापस नहीं करते हैं बल्कि इसके बजाय निर्दिष्ट वस्तु के एक हिस्से के संदर्भ में हैं, उदाहरण के लिए

template<class T> 
T&& getHead(std::vector<T>&& input) { 
    return std::move(input.front()); 
} 
+0

@ जारोड 42 यहां नहीं चल रहा है हटाए गए प्रतिलिपि निर्माता को कॉल करेगा। मुझे यकीन नहीं है कि क्या एनआरवीओ बिल्कुल लागू होगा, क्योंकि समारोह के अंदर कोई वस्तु नहीं है। –

+0

पूरी तरह से अग्रेषित फ़िल्टर फ़ंक्शंस के लिए उपयोगी। +1! –

5

यह ठीक है std::move है - std::move निष्पादन का परिणाम एक xvalue है। इसके अलावा यह कहना मुश्किल है क्योंकि मुख्य रूप से फ़ंक्शन से संदर्भ लौटने में मुख्य बात एक बुरी चीज है। लेकिन शायद कोई इस तरह के एक समारोह के एक और चालाक उपयोग के साथ आ जाएगा।

+0

@DeanSeo, वास्तव में, लेकिन फ़ंक्शन से किसी संदर्भ के लिए लौटने के अलावा किसी अन्य चीज़ के लिए रिटर्न प्रकार में रेवल्यू संदर्भ का उपयोग नहीं कर सकता है (इससे कोई फर्क नहीं पड़ता कि यह किस प्रकार है) फ़ंक्शन से गलत है, सिवाय इसके कि यह कॉन्स और कॉन्स्ट रावल्यू संदर्भ बेकार है – ixSci

+0

मेरी पिछली टिप्पणी को हटाने के लिए खेद है।बीटीडब्ल्यू, 'कॉन्स्ट रावल्यू संदर्भ जो लौटाया जा रहा है' एक xvalue है। तो संक्षेप में, xvalues ​​लौटने व्यावहारिक रूप से बेकार है, आप कह रहे हैं? : पी –

+0

@DeanSeo, मैं जो कह रहा हूं वह यह है कि किसी फ़ंक्शन के भीतर स्टैक पर बनाई गई चीज़ के संदर्भ को वापस करना गलत है। तो मुझे कोई उपयोग उदाहरण नहीं दिखाई देता है जब हम 'std :: move' के साथ हमारे मामले के अलावा रिटर्न प्रकार के रूप में एक रावल्यू संदर्भ का उपयोग कर सकते हैं (हमें बाहर से कुछ मिला है और इसे एक रावल्यू रेफरी लौटाया है)। इसका मतलब यह नहीं है कि इस तरह का उपयोग नहीं है - भाषा सुविधाओं को बार-बार फिर से खोजा जाता है। लेकिन अभी के लिए मैंने इस मामले में कुछ भी नहीं सुना है। – ixSci

3

क्या हम कभी भी ऐसे फ़ंक्शन का उपयोग करने की आवश्यकता रखते हैं जहां वापसी का प्रकार एक रावल्यू संदर्भ है, जो एक xvalue है?

यह कंटेनर कक्षाओं में इस्तेमाल, उदाहरण के लिए tuple एक get अधिभार कि इस तरह दिखता है है:

template< std::size_t I, class... Types > 
typename std::tuple_element<I, tuple<Types...> >::type&& 
    get(tuple<Types...>&& t); 

मुझे लगता है कि std::optional और std::variant में सी ++ 17 दोनों एक समान भार के होगा।

दी, केवल बात कुछ बहुत ही विशेष परिस्थितियों में std::move टाइप करने के लिए, की तरह से बचने के लिए है:

auto x = std::get<1>(f()); 

कहाँ f मूल्य द्वारा एक टपल देता है।

+0

कन्स्ट्रक्टरों को भी कैसे सहेजने के लिए एक महान उदाहरण है जहां उनकी आवश्यकता नहीं है (यानी सैद्धांतिक रूप से यह केवल अंतराल में परिवर्तित किए गए xvalues ​​को वापस कर सकता था, लेकिन इसके लिए अनावश्यक रूप से, एक चाल या एक प्रतिलिपि बनाने की आवश्यकता होगी, जो कि ' हमेशा उपलब्ध नहीं)। –

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

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