दिलचस्प पोस्ट
एक गीतम भंडार के पहले दो कमानों को जोड़ता है? गतिशील रूप नाम विशेषता <input type = "text" name = "{{variable-name}}"> Angularjs में क्या एंडवॉव () वैकल्पिक, सॉर्ट-इन वैकल्पिक, या निश्चित रूप से वैकल्पिक नहीं है? एंड्रॉइड: अधिकतम अनुमति चौड़ाई और बिटमैप की ऊंचाई अंतिम डाक कोड और ज़िप रीगेक्स क्या है? सी # आंशिक रूप से एएलआरआईएलआईटी <टी> को कैसे कार्यान्वित करता है? मैं NSURL सत्र के लिए डेटा कैसे प्राप्त करूं? साझा सत्र ()। DataTaskWithRequest NHibernate मैं एक IList <string> संपत्ति के विरुद्ध कैसे क्वेरी करूं? Xcode 4 स्थैतिक लाइब्रेरी निर्भरता से सार्वजनिक हेडर फाइलों को नहीं ढूँढ सकता AngularJS: कैसे एक jsonp अनुरोध बनाने के लिए एक स्ट्रिंग को सी ++ ऊपरी केस में कनवर्ट करें बाहरी स्पर्श को बंद करने से एंड्रॉइड गतिविधि संवाद रोकें Javascript / JQuery का उपयोग करते हुए JSON वस्तुओं में अंतर IntelliJ निरीक्षण "प्रतीक का समाधान नहीं कर सकता" देता है, लेकिन फिर भी कोड संकलित करता है मैं यूआईएलबल में टेक्स्ट के उपस्ट्रिंग के लिए CGRect कैसे खोजूं?

Std :: move () क्या है, और इसका उपयोग कब किया जाना चाहिए?

  1. यह क्या है?
  2. यह क्या करता है?
  3. इसे कब उपयोग किया जाना चाहिए?

अच्छे संबंधों की सराहना की जाती है

वेब के समाधान से एकत्रित समाधान "Std :: move () क्या है, और इसका उपयोग कब किया जाना चाहिए?"

http://en.wikipedia.org/wiki/C%2B%2B11#Rvalue_references_and_move_constructors
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2027.html#Move_Semantics

  1. कंसल्टेंट्स की प्रतिलिपि बनाने के अलावा, सी ++
    (और असाइनमेंट ऑपरेटरों की प्रतिलिपि बनाने के अलावा, उनके पास असाइनमेंट ऑपरेटरों को स्थानांतरित किया गया है।)
  2. चाल निर्मात का उपयोग प्रतिलिपि कन्स्ट्रक्टर के बजाय किया जाता है, यदि वस्तु का प्रकार "rvalue-reference" ( Type && ) है
  3. std::move() एक कलाकार है जो किसी वस्तु के संदर्भ में एक रवैया बनाता है, जिससे इसे आगे बढ़ने के लिए सक्षम किया जा सकता है।

प्रतियों से बचने का यह एक नया सी + + तरीका है उदाहरण के लिए, एक std::vector कन्स्ट्रक्टर का इस्तेमाल करते हुए, एक std::vector अपने आंतरिक सूचक को डेटा को नए ऑब्जेक्ट में कॉपी कर सकता है, ले जाया गया ऑब्जेक्ट को गलत स्थिति में छोड़कर सभी डेटा कॉपी करने से बचा सकता है। यह सी ++ – वैध होगा।

स्थानांतरित शब्दों, रैवल्यू, सही फ़ॉरवर्डिंग के लिए Googling का प्रयास करें।

जब आप एक वस्तु की सामग्री को "कहीं" में कॉपी करने के बिना "स्थानांतरित" करने की ज़रूरत करते हैं, तो आप उस स्थान का उपयोग कर सकते हैं (जैसे सामग्री को दोहराया नहीं गया है, इसलिए यह कुछ गैर-कॉपी करने योग्य वस्तुओं पर उपयोग हो सकता है, जैसे कि एक अनूठे_पीटीआर)। एक ऑब्जेक्ट के लिए एक अस्थायी ऑब्जेक्ट की प्रतिलिपि (और बहुत समय बचाने के लिए) बिना सामग्री लेने के लिए भी संभव है, std :: move के साथ

यह कड़ी वास्तव में मेरी मदद करती है:

http://thbecker.net/articles/rvalue_references/section_01.html

मुझे माफ़ करना, अगर मेरा उत्तर बहुत देर से आ रहा है, लेकिन मैं std :: चाल के लिए एक अच्छी लिंक की तलाश कर रहा था, और मुझे थोड़ा सा "अष्ट" ऊपर लिंक मिला।

इसने आर-वैल्यू रेफरेंस पर जोर दिया, जिसके संदर्भ में आपको उनका इस्तेमाल करना चाहिए, और मुझे लगता है कि यह अधिक विस्तृत है, यही कारण है कि मैं यहां इस लिंक को साझा करना चाहता था।

1. "यह क्या है?"

जबकि std::move() "एक समारोह की तरह दिखता है" – मैं कहूंगा कि यह वास्तव में एक फ़ंक्शन नहीं है यह एक कनवर्टर की तरह है, जिस तरह से कंपाइलर अभिव्यक्ति के मान को मानता है।

2. "यह क्या करता है?"

ध्यान देने वाली पहली बात यह है कि std::move() वास्तव में कुछ भी नहीं हिलता है

यदि आपने कभी एनीमेशन श्रृंखला ब्लीच देखा है – यह क्विन्सी सेले शनइडर के रिशी नरम के बराबर है ( इस दृश्य में इसके उपयोग को भी देखें)।

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

आप मुझे लूट ले सकते हैं, कुछ भी ले जा सकते हैं जो मैं ले रहा हूं और कहीं और इसका इस्तेमाल कर रहा हूं (क्योंकि मैं वैसे भी जल्द नष्ट हो रहा हूं) "।

दूसरे शब्दों में, जब आप std::move(x) उपयोग करते हैं, तो आप अपने आप को (या कंपाइलर) को x को कैनिबिलाइज करने की अनुमति दे रहे हैं। इसलिए यदि x में है, तो कहते हैं, मेमोरी में अपना स्वयं का बफ़र – std::move() आईएनजी के बाद आप उस बफ़र का उपयोग जो कुछ भी आप चाहते हैं

3. "इसे कब उपयोग किया जाना चाहिए?"

यह सवाल पूछने का एक और तरीका है, "मैं किसी ऑब्जेक्ट के संसाधनों का उपयोग किस प्रकार करेगा / करूं?" ठीक है, अगर आप एप्लिकेशन कोड लिख रहे हैं, तो शायद आप कम्पाइलर द्वारा बनाई गई अस्थायी ऑब्जेक्ट्स के साथ बहुत कुछ घसीट नहीं करेंगे। इसलिए मुख्य रूप से आप इसे कन्स्ट्रक्टर, ऑपरेटर विधियों, एसटीएल-एल्गोरिदम जैसे कार्यों आदि में कर सकते हैं, जहां ऑब्जेक्ट निर्मित होते हैं और स्वचालित रूप से बहुत ही नष्ट हो जाते हैं। बेशक, यह सिर्फ अंगूठे का एक नियम है

एक ठेठ उपयोग 'प्रतिलिपि बनाने के बजाय एक वस्तु से दूसरे स्थान पर' चलती 'संसाधन होता है। @गुइलाउम इस पृष्ठ पर लिंक है जिसमें एक सीधा सीधा उदाहरण है: कम प्रतिलिपि वाले दो ऑब्जेक्ट्स गमागमन

 template <class T> swap(T& a, T& b) { T tmp(a); // we now have two copies of a a = b; // we now have two copies of b (+ discarded a copy of a) b = tmp; // we now have two copies of tmp (+ discarded a copy of b) } 

चाल के उपयोग से आपको उन्हें प्रतिलिपि बनाने के बजाय संसाधनों को स्वैप करने की अनुमति मिलती है:

 template <class T> swap(T& a, T& b) { T tmp(std::move(a)); a = std::move(b); b = std::move(tmp); } 

टी के बारे में सोचें, जब टी है, कहते हैं, आकार n के vector<int> पहले संस्करण में आप 3 * n तत्वों को पढ़ते और लिखते हैं, दूसरे संस्करण में आप मूल रूप से पढ़ते हैं और केवल 3 पॉइंटर्स को वैक्टर बफ़र्स में लिखते हैं। बेशक, कक्षा टी को पता होना चाहिए कि कैसे चलती है; आपके पास काम करने के लिए कक्षा टी के लिए एक चाल-असाइनमेंट ऑपरेटर और एक चालन-कन्स्ट्रक्टर होना चाहिए।

std :: कदम खुद वास्तव में बहुत कुछ नहीं करता है मैंने सोचा था कि इसे किसी ऑब्जेक्ट के लिए ले जाया गया कंसट्रक्टर कहा जाता है, लेकिन यह वास्तव में केवल एक प्रकार का डाली करता है (एक लावल्यू वैरिएबल को एक रैवल्यू में ढंकते हुए इतना कहा जाता है कि चालक एक चालन निर्माता या असाइनमेंट ऑपरेटर के लिए तर्क के रूप में पारित किया जा सकता है)।

इसलिए std :: चाल का उपयोग केवल चाल शब्दों का उपयोग करने के लिए अग्रदूत के रूप में किया जाता है। स्थानांतरित करें शब्दों अस्थायी वस्तुओं से निपटने के लिए अनिवार्य रूप से एक प्रभावी तरीका है।

ऑब्जेक्ट A = B + C + D + E + F;

यह अच्छा दिखने वाला कोड है, लेकिन ई + एफ एक अस्थायी वस्तु का उत्पादन करती है। तब डी + अस्थायी एक और अस्थायी ऑब्जेक्ट पैदा करता है और इसी तरह। एक कक्षा के प्रत्येक सामान्य ऑपरेटर में, गहरी प्रतियां होती हैं

उदाहरण के लिए

 Object Object::operator+ (const Object& rhs) { Object temp (*this); // logic for adding return temp; } 

इस फ़ंक्शन में अस्थायी ऑब्जेक्ट का निर्माण बेकार है – इन अस्थायी वस्तुओं को लाइन के अंत में हटा दिया जाएगा क्योंकि वे गुंजाइश से बाहर जाते हैं।

हम स्थानांतरित शब्दों का इस्तेमाल अस्थायी वस्तुओं को "लूट" करने और कुछ ऐसा करने के लिए कर सकते हैं

  Object& Object::operator+ (Object&& rhs) { // logic to modify rhs directly return rhs; } 

यह अनावश्यक गहरी प्रतियां बनी रहती है। उदाहरण के संदर्भ में, एकमात्र ऐसा हिस्सा जहां गहरी प्रतिलिपि होती है अब ई + एफ। बाकी का उपयोग स्थानान्तरण शब्दों का उपयोग करता है इस कदम निर्माता या असाइनमेंट ऑपरेटर को भी ए को परिणाम प्रदान करने के लिए लागू किया जाना चाहिए।

1.) यह क्या है? std::move() एक rvalue संदर्भ को कास्टिंग के लिए C ++ मानक पुस्तकालय से एक समारोह है।

सरलता std::move(t) के बराबर है:

 static_cast<T&&>(t); 

एक रैवल्यू एक अस्थायी है जो अभिव्यक्ति से परे रहती है जो इसे परिभाषित करती है, जैसे कि एक मध्यवर्ती कार्य परिणाम जो कि किसी चर में संग्रहीत नहीं होता है

 int a = 3; // 3 is a rvalue, does not exist after expression is evaluated int b = a; // a is a lvalue, keeps existing after expression is evaluated 

Std :: move () के लिए कार्यान्वयन N2027 में दिया गया है : "Rvalue संदर्भों का संक्षिप्त परिचय" निम्नानुसार है:

 template <class T> typename remove_reference<T>::type&& std::move(T&& a) { return a; } 

जैसा कि आप देख सकते हैं, std::move एक मूल्य ( T ), संदर्भ प्रकार ( T& ) या रैवल्यू संदर्भ ( T&& T& ) के साथ बुलाए std::move रिटर्न T&& कोई फर्क नहीं पड़ता।

2.) यह क्या करता है? एक कलाकार के रूप में, यह रनटाइम के दौरान कुछ भी नहीं करता है कंपाइलर को बताने के लिए समय को संकलित करना केवल प्रासंगिक है जिसे आप संदर्भ के रूप में संदर्भ के रूप में जारी रखना चाहते हैं।

 foo(3 * 5); // obviously, you are calling foo with a temporary (rvalue) int a = 3 * 5; foo(a); // how to tell the compiler to treat `a` as an rvalue? foo(std::move(a)); // will call `foo(int&& a)` rather than `foo(int a)` or `foo(int& a)` 

यह क्या नहीं करता है:

  • तर्क की एक प्रति बनाओ
  • कॉपी कन्स्ट्रक्टर को कॉल करें
  • तर्क वस्तु बदलें

3.) यह कब इस्तेमाल किया जाना चाहिए? आपको std::move उपयोग करना चाहिए यदि आप फ़ंक्शन कॉल करना चाहते हैं जो एक तर्क के साथ ले जाने वाले शब्दों का समर्थन करते हैं जो एक आरवल्यू (अस्थायी अभिव्यक्ति) नहीं है।

यह मेरे लिए निम्नलिखित अनुवर्ती प्रश्नों की मांग करता है:

  • कदम सिमेंटिक क्या हैं? शब्दों की प्रतिलिपि बनाने के विपरीत शब्दों को स्थानांतरित करना एक प्रोग्रामिंग तकनीक है जिसमें एक ऑब्जेक्ट के सदस्य एक अन्य ऑब्जेक्ट के सदस्यों की प्रतिलिपि बनाने के बजाय 'ओवरिंग' के द्वारा आरंभ किए जाते हैं। ऐसे 'ले लो' केवल पॉइंटर्स और संसाधन हैंडल के साथ समझ में आता है, जो कम से कम डेटा की बजाय पॉइंटर या पूर्णांक संभाल की प्रतिलिपि करके तब्दील हो सकता है।

  • वर्गों और ऑब्जेक्ट किस तरह का चालन सिमेंटिक्स का समर्थन करते हैं? यह एक डेवलपर के रूप में है कि आप अपने स्वयं के कक्षा में स्थानांतरित शब्दों को लागू करने के लिए अगर इन्हें कॉपी करने के बजाय उनके सदस्यों को स्थानांतरित करने से फायदा होगा। एक बार जब आप चाल शब्दों को लागू करते हैं, तो आप कई लाइब्रेरी प्रोग्रामर्स से सीधे काम से लाभ उठाएंगे, जिन्होंने चाल शब्दों के साथ कक्षाओं को कुशलतापूर्वक प्रबंधित करने के लिए समर्थन जोड़ा है।

  • कंपाइलर अपने आप से इसे क्यों नहीं समझ सकता? कंपाइलर सिर्फ एक फ़ंक्शन के अतिरिक्त अधिभार को कॉल नहीं कर सकता जब तक कि आप ऐसा नहीं कहें। आपको संकलक को चुनने में मदद करनी चाहिए कि क्या फ़ंक्शन के नियमित या स्थानांतरित संस्करण को कॉल किया जाना चाहिए।

  • किस परिस्थिति में मैं संकलक को यह कहना चाहूंगा कि उसे एक चर के रूप में एक रवैये के रूप में इलाज करना चाहिए? यह सबसे अधिक संभावना टेम्प्लेट या लाइब्रेरी फ़ंक्शंस में होगा, जहां आप जानते हैं कि एक मध्यवर्ती परिणाम बचाया जा सकता है।