2013-06-17 7 views
18

विवरण के लिए कदम कहते हैंवहाँ rvalue संदर्भ और एसटीडी के लिए स्थिर डाली के बीच कोई अंतर :: स्थिर डाली के लिए

तो कर NEW_TYPE हो एक rvalue संदर्भ प्रकार है, static_cast XValue को अभिव्यक्ति के मूल्य में कनवर्ट करता है। इस प्रकार का static_cast std :: move में move semantics को लागू करने के लिए उपयोग किया जाता है। (सी ++ 11)

क्या यह पुष्टि करता है कि निम्नलिखित समकक्ष हैं?

(ए)

X x1; 
X x2 = static_cast<X&&>(x1); 

(बी)

X x1; 
X x2 = std::move(x1); 
+4

वे बराबर हैं लेकिन चाल त्रुटियों की संभावना कम है। – user1353535

उत्तर

31

हाँ वहाँ एक बहुत ही महत्वपूर्ण अंतर है: std::move दस्तावेजों है कि आप क्या करना चाहते हैं। इसके अलावा कास्ट भूल गए & या गलत प्रकार X जैसी त्रुटियों को लिखने के लिए प्रवण है।

जैसा कि देखा जा सकता है, std::move टाइप करने के लिए भी कम है।

+3

मैं केवल 'moveic_cast ' "का उपयोग करता हूं जब 'move' * नहीं *' constexpr' है और मुझे उस विशेषता की आवश्यकता है। – CTMacUser

1

टी & & सी ++ 11 में rValue संदर्भ है। वे सी ++ 98,03 से लैवल्यू संदर्भ की तरह व्यवहार करते हैं। उनका लक्ष्य - आगे बढ़ने के लिए उम्मीदवार बनना। सी ++ 98 में ऐसे निर्माण को

std :: move - रैवल्यू में अभिव्यक्ति बदलता है। इसे rvalue_cast कहा जा सकता है, लेकिन ऐसा कीवर्ड मौजूद नहीं है।

टी & & सिद्धांत में संभव टाइप करने के लिए स्पष्ट कलाकार। रियल standart कुछ पैसे खर्च, लेकिन ISO/IEC 14882:2011 के मसौदे में मौजूद इस तरह की जानकारी

5.2.9 स्टेटिक डाली

8)

lvalue करने वाली rvalue (4.1), सरणी है करने वाली सूचक (4.2), और समारोह करने के लिए सूचक (4.3) रूपांतरण संकार्य के लिए लागू कर रहे हैं ....

देखने का व्यावहारिक दृष्टिकोण से इसे और अधिक std :: चाल का उपयोग करने के लिए सुविधाजनक है।

#include <stdio.h> 
#include <utility> 

class A 
{ 
public: 
A() {printf ("A()" "\n");} 
A (const A &) {printf ("A (&)" "\n");} 
A (A &&) {printf ("A (&&)" "\n");} 
A (const A &&) {printf ("A (const &&)" "\n");} 
~ A() {printf ("~ A()" "\n");} 
}; 


int main() 
{ 
const A obj; 
A obj2 (std::move (obj)); // 1-st approach 
A obj3 (static_cast <const A&&> (obj)); // 2-nd approach 
} 

मुझे 1-सेंट दृष्टिकोण का सवाल है

  • अधिक सुविधाजनक (आप स्थिरांक को static_cast प्रदर्शन करना चाहिए है एक & &, या एक & & रहे हैं: इस तरह के उदाहरण कल्पना कीजिए?)
  • अधिक स्पष्ट रूप से (मैं खोज पाठ संपादक में std :: परियोजना में कदम)
  • त्रुटि-रहित होता है जब सॉफ्टवेयर डेवलपर लिखने कोड
+0

'rvalue_cast' _keyword_ की कोई आवश्यकता नहीं है। बस 'टेम्पलेट टेम्पलेट constexpr auto rvalue_cast (T && t) {वापसी std :: move (t); }; 'यदि आप वास्तव में उस नाम का उपयोग करना चाहते हैं। – rubenvb

-1

आप static_cast<A &&>(a) उपयोग कर सकते हैं खोजने के लिए जब एक एक है का उपयोग कर सकते रावल्यू, लेकिन आपको std::move(a) का उपयोग नहीं करना चाहिए।
जब आप A && a = std::move(A()) का उपयोग करते हैं, तो आपको एक खतरनाक संदर्भ मिलता है।

मूल विचार यह है कि अस्थायी जीवनकाल को "इसे पारित करने" द्वारा आगे बढ़ाया नहीं जा सकता है: एक दूसरा संदर्भ, जिसे अस्थायी रूप से बाध्य किया गया था, से शुरू किया गया, इसका जीवनकाल प्रभावित नहीं करता है।

std::move के कार्यान्वयन है कुछ हद तक

तरह
template <typename T> 
constexpr decltype(auto) move(T && __t) noexcept // when used in std::move(A()), 
                // the lifetime of the temporary object is extended by __t 
{ 
    return static_cast<typename std::remove_reference<T>::type &&>(__t); // a xvalue returned, no lifetime extension 
} 

auto && a = std::move(A()); // the anonymous object wiil be destructed right after this line 
+0

मुझे नहीं लगता कि आप अपने दूसरे उदाहरण में लटकने वाले संदर्भ कैसे प्राप्त करते हैं। साथ ही, 'std :: move (a) 'के साथ क्या गलत है जब' a' एक रावल है? 'Std :: move ((const int और) ए का नतीजा) 'केवल' const int && 'है, जो आप चाहते हैं। – SirGuy

+0

@SirGuy फ़ंक्शन कॉल में संदर्भ पैरामीटर के लिए अस्थायी बाध्य उस फ़ंक्शन कॉल वाली पूर्ण अभिव्यक्ति के अंत तक मौजूद है: यदि फ़ंक्शन एक संदर्भ देता है, जो पूर्ण अभिव्यक्ति को पार करता है, तो यह एक खतरनाक संदर्भ बन जाता है। 'चाल' एक तर्क के रूप में जाने-जाने वाली प्रवीण अभिव्यक्ति के लिए एक रावल्यू संदर्भ लेता है। –

+0

'ए && a = std :: move (ए()); 'एक लटकती संदर्भ (जैसा कि इसके static_cast संस्करण होगा) ...' ए 'एक संदर्भ नहीं है, इसलिए एक खतरनाक नहीं है –

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