2014-10-21 3 views
10

कुछ शोध करने के बाद, मुझे लगता है कि C++11 has a defect उन आवंटकों के साथ जिन्हें प्रकार को चलने योग्य/प्रतिलिपि बनाने की आवश्यकता होती है। मुझे यकीन है कि यह इस समस्या का कारण है, हालांकि मैं हटाए गए और घोषित चाल semantics के बीच व्यवहार के बारे में उलझन में हूँ।हटाए गए कदम सेमेन्टिक्स क्यों std :: vector के साथ समस्याएं पैदा करते हैं?

मैं निम्नलिखित कोड है जो दोनों MSVC12 और बजना पर संकलित करने के लिए विफल रहता है:

xmemory0(600): error C2280: 'Copyable::Copyable(Copyable &&)' : attempting to reference a deleted function

और बजना पर (live sample):

#include <vector> 

class Copyable 
{ 
public: 
    Copyable() = default; 

    Copyable(Copyable const& other) 
     : m_int(other.m_int) 
    {} 

    Copyable& operator= (Copyable const& other) 
    { 
     m_int = other.m_int; 
     return *this; 
    } 

    Copyable(Copyable&&) = delete; 
    Copyable& operator= (Copyable&&) = delete; 

private: 
    int m_int = 100; 
}; 

int main() 
{ 
    std::vector<Copyable> objects; 
    objects.push_back(Copyable{}); 
} 

इस के साथ MSVC पर संकलित करने के लिए विफल रहता है

new_allocator.h:120:23: error: call to deleted constructor of 'Copyable'

दोनों मामलों में, जब मैं स्पष्ट रूप से हटाए गए कदम निर्माण/असाइन को हटा देता हूं विधियों, कोड संकलन। AFAIK जब आप कॉपी असाइन/निर्माण विधियों की घोषणा करते हैं, तो संकलक स्पष्ट रूप से संबंधित चाल सदस्यों को घोषित नहीं करता है। तो उन्हें अभी भी प्रभावी रूप से हटा दिया जाना चाहिए, है ना? जब मैं चाल निर्माण/असाइनमेंट के स्पष्ट विलोपन को हटाता हूं तो कोड संकलित क्यों होता है?

सामान्य रूप से इस सी ++ 11 दोष के लिए अच्छा कामकाज क्या है? मैं नहीं चाहता कि मेरी वस्तुएं चलने योग्य हों (लेकिन वे कॉपी करने योग्य हैं)।

+0

एक प्रतिलिपि के माध्यम से आगे बढ़ना लागू करें? –

+0

इसके अलावा: [सी ++ 11-हटाए गए फ़ंक्शन ओवरलोड रिज़ॉल्यूशन में क्यों भाग लेते हैं?] (Http: // stackoverflow।कॉम/प्रश्न/14085620/क्यों-डू-सी 11-हटाए गए-फ़ंक्शंस-भाग-इन-ओवरलोड-रिज़ॉल्यूशन) – Nawaz

उत्तर

14

फ़ंक्शन को हटाने से यह घोषित नहीं होता है।

एक हटाए गए फ़ंक्शन को घोषित किया गया है और ओवरलोड रिज़ॉल्यूशन में भाग लेता है, लेकिन यदि आप इसे कॉल करने का प्रयास करते हैं तो एक त्रुटि उत्पन्न होती है।

यदि आप अपने चालक कन्स्ट्रक्टर की घोषणा करने में विफल रहते हैं, तो संकलक एक प्रति निर्माण निर्माता के रूप में नहीं बनाएगा। एक रैल्यू पर ओवरलोड रिज़ॉल्यूशन आपके प्रतिलिपि निर्माता को मिलेगा, जो शायद आप चाहते हैं।

आपने अपने foo(foo&&)=delete के साथ क्या कहा था, "अगर कोई इस ऑब्जेक्ट को स्थानांतरित करने का प्रयास करता है, तो त्रुटि उत्पन्न करता है"।

void do_stuff(int x) { std::cout << x << "\n"; } 
void do_stuff(double) = delete; 

void do_stuff2(int x) { std::cout << x << "\n"; } 
//void do_stuff2(double) = delete; 

int main() { 
    do_stuff(3); // works 
    //do_stuff(3.14); // fails to compile 
    do_stuff2(3); // works 
    do_stuff2(3.14); // works, calls do_stuff2(int) 
} 

इस में थोड़ा और अधिक भ्रमित करता है कि आपके ऊपर समस्या के साथ ही हिस्सा है कि विशेष सदस्य कार्यों को स्वचालित रूप से बनाई गई हैं या नहीं थोड़ा रहस्यमय नियमों पर आधारित है:

मैं अंतर यहाँ वर्णन कर सकते हैं।

10
Copyable(Copyable&&) = delete; 
Copyable& operator= (Copyable&&) = delete; 

(वास्तव में जानकार और मेरा मतलब है,) जब तक आप इस कदम अर्थ विज्ञान में एक विशेषज्ञ हैं, कभी नहीं विशेष चाल के सदस्यों को हटा दें। यह वही नहीं करेगा जो आप चाहते हैं। यदि आप किसी और के कोड की समीक्षा करते हैं, जिसने इसे किया है, तो इसे कॉल करें। स्पष्टीकरण वास्तव में ठोस होना चाहिए, और नहीं "क्योंकि मैं नहीं चाहता कि प्रकार आगे बढ़े।"

बस इसे मत करें।

जो भी आप चाहते हैं उसे करने का सही तरीका है बस अपनी प्रति सदस्यों को घोषित/परिभाषित करना। चाल के सदस्यों को निहित रूप से अवरुद्ध किया जाएगा (हटाया नहीं गया है, लेकिन वास्तव में वहां नहीं है)। बस सी ++ 98/03 लिखें।

अधिक जानकारी के लिए, see this answer

+1

+1 यह व्यावहारिक सलाह है जो खोजना मुश्किल है, भले ही वहां बहुत सारे उपयोगी संदर्भ हैं। –

+2

इन सभी महान सामानों के साथ एक छोटी सी पुस्तक लिखने के बारे में (सालों से चलने वाले, पैरामीटर पासिंग, क्लास डिज़ाइन, तिथियां, क्रमपरिवर्तन और धागे) जिन्हें आपने सालों में एसओ (और libC++ में उपयोग किया) पर एक साथ रखा है? जैसे @ShafikYaghmour सही ढंग से कहता है, यह खोजने और बिखरे हुए सभी को बहुत मुश्किल है। – TemplateRex

+0

@ टेम्पलेटरेक्स: समय की तलाश में ... –

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