मैं स्थानांतरित वस्तु से क्या कर सकता हूं?


138

क्या मानक ठीक से परिभाषित करता है कि एक वस्तु को एक बार ले जाने के बाद मैं क्या कर सकता हूं? मैं सोचता था कि आप एक स्थानांतरित वस्तु से क्या कर सकते हैं क्या यह विनाश है, लेकिन यह पर्याप्त नहीं होगा।

उदाहरण के लिए, swapमानक लाइब्रेरी में परिभाषित फंक्शन टेम्पलेट लें :

template <typename T>
void swap(T& a, T& b)
{
    T c = std::move(a); // line 1
    a = std::move(b);   // line 2: assignment to moved-from object!
    b = std::move(c);   // line 3: assignment to moved-from object!
}

जाहिर है, स्थानांतरित वस्तुओं से असाइन करना संभव होगा, अन्यथा लाइनें 2 और 3 विफल हो जाएंगी। तो मैं स्थानांतरित वस्तुओं से और क्या कर सकता हूं? वास्तव में मुझे ये विवरण मानक में कहां मिलेंगे?

(वैसे, यह पंक्ति 1 के T c = std::move(a);बजाय क्यों है T c(std::move(a));?)

जवाबों:


53

चालित-से ऑब्जेक्ट एक अनिर्दिष्ट, लेकिन मान्य, स्थिति में मौजूद हैं। इससे पता चलता है कि जब तक वस्तु ज्यादा देर करने में सक्षम नहीं हो सकती है, तब तक उसके सभी सदस्य कार्यों को अभी भी परिभाषित व्यवहार प्रदर्शित करना चाहिए - जिसमें operator=- और उसके सभी सदस्य एक परिभाषित स्थिति में हैं- और इसे अभी भी विनाश की आवश्यकता है। मानक कोई विशिष्ट परिभाषा नहीं देता है क्योंकि यह प्रत्येक यूडीटी के लिए अद्वितीय होगा, लेकिन आप मानक प्रकारों के लिए विशिष्टताओं को खोजने में सक्षम हो सकते हैं। कंटेनरों की तरह कुछ अपेक्षाकृत स्पष्ट हैं - वे बस अपनी सामग्री को चारों ओर ले जाते हैं और एक खाली कंटेनर एक अच्छी तरह से परिभाषित वैध स्थिति है। प्रिमिटिव्स स्थानांतरित-से-ऑब्जेक्ट को संशोधित नहीं करते हैं।

साइड नोट: मेरा मानना ​​है T c = std::move(a)कि यदि मूव कंस्ट्रक्टर (या कंस्ट्रक्शन कंस्ट्रक्टर अगर कोई मूव उपलब्ध नहीं है तो) स्पष्ट है कि फंक्शन फेल हो जाएगा।


26
इसके सभी सदस्य कार्य परिभाषित व्यवहार का प्रदर्शन नहीं करेंगे। केवल बिना किसी पूर्व शर्त के। उदाहरण के लिए आप शायद pop_backएक स्थानांतरित नहीं करना चाहते हैं vector। लेकिन आप निश्चित रूप से पता लगा सकते हैं कि क्या यह है empty()
हावर्ड हिनांत

6
@ हावर्ड हेंनट: pop_backएक खाली से vectorवैसे भी अपरिभाषित व्यवहार होता है, स्मृति से, इसलिए मुझे पूरा यकीन है कि pop_backएक स्थानांतरित वेक्टर से अपरिभाषित व्यवहार प्रदर्शित करना सुसंगत है।
पिल्ला

12
हम स्थानांतरित वस्तुओं से चर्चा कर रहे हैं। खाली अवस्था में होने वाली वस्तु नहीं। स्थानांतरित-से ऑब्जेक्ट्स में एक अनिर्दिष्ट स्थिति होती है (जब तक कि अन्यथा निर्दिष्ट न हो)। [lib.types.movedfrom]
हावर्ड हिनांत

5
@ हॉवर्ड अनिर्दिष्ट, लेकिन मान्य है, इसलिए pop_backअभी भी किसी भी वैध वेक्टर पर व्यवहार करता है (यह एक खाली वेक्टर भी हो सकता है)।
ईसाई रौ

1
इस संदर्भ में अनिर्दिष्ट और वैध क्या है?
अंकुर एस

114

17.6.5.15 [lib.types.movedfrom]

C ++ मानक पुस्तकालय में परिभाषित प्रकारों की वस्तुओं को (12.8) से स्थानांतरित किया जा सकता है। चाल परिचालन स्पष्ट रूप से निर्दिष्ट या अंतर्निहित रूप से उत्पन्न हो सकता है। जब तक अन्यथा निर्दिष्ट नहीं किया जाता है, इस तरह की स्थानांतरित-से-ऑब्जेक्ट को एक मान्य लेकिन अनिर्दिष्ट स्थिति में रखा जाएगा।

जब कोई ऑब्जेक्ट अनिर्दिष्ट स्थिति में होता है, तो आप उस ऑब्जेक्ट पर कोई भी ऑपरेशन कर सकते हैं जिसमें कोई पूर्व शर्त नहीं है। यदि आपके द्वारा निष्पादित की जाने वाली पूर्व शर्त के साथ कोई ऑपरेशन है, तो आप सीधे उस ऑपरेशन को नहीं कर सकते हैं क्योंकि आपको नहीं पता है कि ऑब्जेक्ट की अनिर्दिष्ट स्थिति पूर्व शर्त को संतुष्ट करती है या नहीं।

उन ऑपरेशनों के उदाहरण जिनमें आमतौर पर पूर्व शर्त नहीं होती हैं:

  • विनाश
  • असाइनमेंट
  • जैसे स्थिरांक पर्यवेक्षकों get, empty,size

उन ऑपरेशनों के उदाहरण जो आम तौर पर पूर्व शर्त रखते हैं:

  • भिन्नता
  • pop_back

यह उत्तर अब यहां वीडियो प्रारूप में दिखाई देता है: http://www.youtube.com/watch?v=vLinb2fgkHk&t=474710s


1
लेकिन मैं बस किसी भी अन्य वस्तु के साथ की तरह पूर्व शर्त की जाँच कर सकता है, है ना?
fredoverflow

6
@FredOverflow जब तक इन जाँचों में स्वयं कोई पूर्व शर्त नहीं है, तब तक।
क्रिश्चियन रौ

1
@ क्रिस: लेकिन यह कैसे एक सामान्य से अलग है, वस्तु से स्थानांतरित नहीं है?
fredoverflow

2
मे-बी एक अलग प्रश्न होना चाहिए, लेकिन क्या इसका मतलब है: अगर मेरे पास char* buffer;और int length;सदस्यों के साथ एक स्ट्रिंग है , तो मेरे कदम निर्माता / असाइनमेंट को दोनों का मूल्य स्वैप (या सेट) करना होगा? या यह ठीक होगा, यदि लंबाई अनिर्दिष्ट थी (जिसका अर्थ है कि emptyऔर sizeअर्थहीन मान लौटाएं)?
अंकलबीन्स

3
@ 6502: आप समझ में नहीं आता। एक C ++ 03 वर्ग "C ++ 0x मानक का उल्लंघन नहीं कर रहा है" क्योंकि एक चाल ctor यदि उत्पन्न होता है तो मानक का उल्लंघन होगा। और C ++ 03 कोड उस वर्ग को स्थानांतरित नहीं करेगा ताकि कोई चाल ctor उत्पन्न होने का कोई कारण न हो।
MSalters
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.