2015-12-31 18 views
16

मेरे पास एक प्रकार है जिसे मैंने कॉपी कन्स्ट्रक्टर से हटा दिया है, और मैं इस प्रकार के vector रखना चाहता हूं, इसलिए मुझे emplace_back के माध्यम से सभी तत्वों को बनाने की आवश्यकता है। लेकिन, emplace_back को एक कॉपी कन्स्ट्रक्टर की आवश्यकता होती है, क्योंकि संकलक emplace_back को तत्काल करने में सक्षम नहीं होने के बारे में चेतावनी देता है क्योंकि कॉपी कन्स्ट्रक्टर हटा दिया गया है। इसे एक प्रतिलिपि बनाने की आवश्यकता क्यों है? मैंने सोचा कि emplace_back का पूरा बिंदु कुछ भी कॉपी किए बिना vector बनाना था। क्या मेरे पास ऑब्जेक्ट्स का vector भी हो सकता है जिसमें कॉपी कॉपीर नहीं है?हटाए गए प्रतिलिपि निर्माता के साथ emplace_back का यह उपयोग क्यों नहीं करता है?

class MyType { 
public: 
    MyType(std::array<double, 6> a) {} 
    MyType(const MyType& that) = delete; 
}; 

int main() { 
    std::vector<MyType> v; 
    std::array<double, 6> a = {1,2,3,4,5,6}; 
    v.emplace_back(a); 
} 

कंपाइलर clang/llvm है।

+0

http://cpp.sh/9v5w यहां काम नहीं करता –

+0

यहां भी http://goo.gl/eLUPjR –

+0

'emplace_back' को कॉपी कन्स्ट्रक्टर की आवश्यकता नहीं है, लेकिन जब वेक्टर की क्षमता स्टोर करने के लिए पर्याप्त नहीं है नया तत्व, वेक्टर को इसके तत्व को पुन: आवंटित करने की आवश्यकता है, इसके लिए प्रतिलिपि/चालक कन्स्ट्रक्टर की आवश्यकता होती है। कॉपी कन्स्ट्रक्टर को हटाकर, आप इसे डिफ़ॉल्ट चाल कन्स्ट्रक्टर उत्पन्न करने से भी रोकते हैं। इस मामले में, एक चालक कन्स्ट्रक्टर घोषित कर सकता है – Danh

उत्तर

20

जब vector का आंतरिक संग्रहण बढ़ता है, तो उसे पुराने स्टोरेज के तत्वों को नए स्थान पर ले जाने की आवश्यकता होगी। कॉपी कन्स्ट्रक्टर को हटाकर, आप इसे डिफ़ॉल्ट चाल कन्स्ट्रक्टर उत्पन्न करने से भी रोकते हैं।

9

emplace_back को कॉल करने में सक्षम होने के लिए, आपका प्रकार EmplaceConstructible या MoveInsertible होना चाहिए। यदि आपने कॉपी कन्स्ट्रक्टर को हटा दिया है तो आपको अपनी कक्षा में एक चालक कन्स्ट्रक्टर देना होगा।

MyType(MyType &&a) {/*code*/} //move constructor 
0

(emplace_back की आवश्यकताओं के लिए this की जाँच करें) आप इस कोड को चलाने का प्रयास करते हैं:

// Example program 
#include <iostream> 
#include <string> 
#include <array> 
#include <vector> 
class MyType { 
public: 
    MyType(std::array<double, 6> a) { 
     std::cout<< "constructed from array\n"; 
     } 
    MyType(const MyType& that){ 
      std::cout<< "copy\n"; 
    } 

    MyType(MyType&& that){ 
      std::cout<< "move\n"; 
    } 
}; 

int main() { 
    std::vector<MyType> v; 
    std::array<double, 6> a = {1,2,3,4,5,6}; 
    v.emplace_back(a); 
} 

आप निम्न परिणाम प्राप्त होगा:

सरणी से निर्माण किया

Live Demo

यह स्पष्ट है कि constructorstd::Array से कहा जाता है। तो, copy constructor के लिए कोई ज़रूरत नहीं है। लेकिन साथ ही यदि आप deletedcopy constructor पर, कंपाइलर एक त्रुटि उठाएगा (कम से कम दो कंपाइलर्स पर मैंने firstsecond) की कोशिश की थी। मुझे लगता है कि कुछ कंपाइलर्स copy constructor के अस्तित्व की जांच करेंगे जब emplace_back का उपयोग करते हैं, भले ही यह इस व्यावहारिक मामले में आवश्यक न हो, जबकि अन्य नहीं। मुझे नहीं पता कि मानक क्या है (कौन सा कंपाइलर सही है या गलत है)।

+1

समस्या यह है कि 'emplace_back' वेक्टर बढ़ने का कारण बन सकता है, जिसके लिए वस्तुओं को जंगम होने की आवश्यकता होती है। और चूंकि 'माईटाइप' में उपयोगकर्ता द्वारा घोषित प्रतिलिपि बनाने वाला है, कोई चालक कन्स्ट्रक्टर उत्पन्न नहीं होता है और कक्षा न तो कॉपी करने योग्य और न ही जंगली है। – Angew

+1

लेकिन कम से कम इस मामले में कोई प्रतिलिपि या चाल नहीं कहा गया था .. तो क्या अंतर है? –

+0

@ हुममहेल्फावी इसे अंततः आवश्यक हो सकता है। जिसका मतलब है कि कुछ मामला है जो उस मामले को संभालने के लिए होगा। और इसके लिए या तो चालक और कॉपी कन्स्ट्रक्टर संकलन समय पर उपस्थित होना चाहिए। – bashrc

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