2015-01-07 5 views
18

const ऑब्जेक्ट पर std :: move क्यों कॉल करता है ऑब्जेक्ट दूसरी ऑब्जेक्ट पर पारित होने पर कॉपी कन्स्ट्रक्टर को कॉल करता है? विशेष रूप से, कोडएक कॉन्स्ट ऑब्जेक्ट पर std :: move क्यों कॉल करता है कॉपी ऑब्जेक्ट को दूसरी ऑब्जेक्ट पर पास करते समय कॉल करता है?

#include <iostream> 

struct Foo { 
    Foo() = default; 
    Foo(Foo && x) { std::cout << "Move" << std::endl; } 
    Foo(Foo const & x) = delete; 
}; 

int main() { 
    Foo const x; Foo y(std::move(x)); 
} 

संदेश के साथ संकलित करने के लिए विफल रहता है:

g++ -std=c++14 test07.cpp -o test07 
test07.cpp: In function 'int main()': 
test07.cpp:10:36: error: use of deleted function 'Foo::Foo(const Foo&)' 
    Foo const x; Foo y(std::move(x)); 
            ^
test07.cpp:6:5: note: declared here 
    Foo(Foo const & x) = delete; 
    ^
Makefile:2: recipe for target 'all' failed 
make: *** [all] Error 1 

निश्चित रूप से, मैं इसे विफल क्योंकि हम एक const मूल्य नहीं ले जा सकते उम्मीद है। साथ ही, मैं उस मार्ग को समझ नहीं पा रहा हूं जो कोड प्रतिलिपि बनाने वाले को कॉल करने का प्रयास करने से पहले लेता है। मतलब, मुझे पता है कि std::move तत्व को x-value में परिवर्तित करता है, लेकिन मुझे नहीं पता कि const के संबंध में उसके बाद चीजें कैसे आगे बढ़ती हैं।

+7

'स्थानांतरित की const'ness ऑब्जेक्ट नहीं बदला गया है, 'Foo const &&' 'Foo && 'से बाध्य नहीं हो सकता है, इसलिए संकलक प्रतिलिपि बनाने वाले को एक्सेस करने का प्रयास करता है, जो विफल हो जाता है क्योंकि यह हटा दिया जाता है। – user657267

+2

मैं चालक ऑपरेटरों पर कोई विशेषज्ञ नहीं हूं, लेकिन शायद यह है कि आप 'कॉन्स्ट' मान पर स्थानांतरित कर सकते हैं, लेकिन इसका नतीजा केवल प्रतिलिपि निर्माता में स्वीकार किया जा सकता है, इसलिए संकलक इसे कॉल करने का निर्णय लेता है। – BWG

+1

"मतलब, मुझे पता है कि std :: move तत्व को x-value में परिवर्तित करता है" असल में, ऐसा नहीं होता है। यह आइटम के लिए एक रैल्यू संदर्भ देता है। –

उत्तर

35

std::move को T const तर्क के साथ T const&& पर कॉल करने के परिणाम का प्रकार T&& पैरामीटर से जुड़ा नहीं जा सकता है। अगला सबसे अच्छा मैच आपकी कॉपी कन्स्ट्रक्टर है, जो हटा दिया गया है, इसलिए त्रुटि।

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

परिणाम समझ में आता है, तो आपको लगता है कि एक const वस्तु के लिए क्या करना है बस std::move फोन करके सक्षम नहीं होना चाहिए।

10

std::move(x) का प्रकार Foo const&& है जो Foo&& से बाध्य नहीं हो सकता है। तर्क T const& के समान है जो T& से जुड़ने में सक्षम नहीं है। हालांकि, आप एक निर्माता हैं जो Foo const&& ले रहे हैं। सबसे अधिक संभावना तुम सच में कदम इसी वस्तु के डेटा लेकिन, जैसे, अपने उदाहरण में कोई डेटा, यानी, निम्नलिखित कोड काम करता है के लिए सक्षम नहीं होगा ठीक है:

#include <iostream> 

struct Foo { 
    Foo() = default; 
    Foo(Foo &&) { std::cout << "Move\n"; } 
    Foo(Foo const&&) { std::cout << "Move const\n"; } 
    Foo(Foo const &) = delete; 
}; 

int main() { 
    Foo const x; Foo y(std::move(x)); 
} 
संबंधित मुद्दे