2010-08-06 21 views
5

क्या कोई कृपया बता सकता है कि मुझे यहां संकलन त्रुटि क्यों मिल रही है - त्रुटि C2558: कक्षा 'std :: auto_ptr < _Ty>': कोई प्रति निर्माता उपलब्ध नहीं है या प्रतिलिपि बनाने वाला घोषित किया जाता है 'स्पष्ट'कोई कॉपी कन्स्ट्रक्टर उपलब्ध नहीं है या कॉपी कन्स्ट्रक्टर को 'स्पष्ट' घोषित किया गया है

#include <memory> 
#include <vector> 
#include <string> 
template<typename T> 
struct test 
{ 
    typedef std::auto_ptr<T> dataptr; 
    typedef std::auto_ptr< test<T> > testptr; 
    test(const T& data): 
    data_(new T(data)) 
    { 
    }; 
    void add_other(const T& other) 
    { 
     others_.push_back(testptr(new test(other))); 
    } 
private: 
    dataptr data_; 
    std::vector<testptr> others_; 
}; 

int main(int argc, char* argv[]) 
{ 
    test<std::string> g("d"); 

    //this is the line that causes the error. 
    g.add_other("d"); 

    return 0; 
} 
+0

यह कुछ समय हो गया है क्योंकि मैंने सी ++ किया है, लेकिन यह 'g = test (" d ") नहीं होना चाहिए;'? –

+0

@ जेसे जे: दोनों ठीक हैं। दोनों तरीकों से थोड़ा अलग व्यवहार होता है जो कि सबसे अधिक शैक्षिक मामलों में एक ही परिणाम देता है। तकनीकी रूप से आपकी विधि एक टेस्ट क्लास तैयार करेगी, फिर इसे जी को शुरू करने के बजाए इसे जी को असाइन करें। यह केवल एक मुद्दा बन जाता है जब आपके पास कस्टम कॉपी/असाइनमेंट/इनिट व्यवहार होते हैं। – Akusete

+0

आप सभी को धन्यवाद। वास्तव में जानकारीपूर्ण जवाब। – Carl

उत्तर

6

असल में std::auto_ptr इस तरह से उपयोग नहीं किया जा सकता है।

others_.push_back(testptr(new test(other))); 

आवश्यक है कि एक प्रति निर्माता है कि एक const& लेता मौजूद है और इस तरह का कोई निर्माता std::auto_ptr लिए मौजूद है। इसे अच्छी तरह से के रूप में व्यापक रूप से के रूप में देखा जाता है, आपको किसी कंटेनर में कभी भी std::auto_ptr का उपयोग नहीं करना चाहिए! यदि आपको समझ में नहीं आता है कि यह क्यों है, तो read this article by Herb Sutter, विशेष रूप से शीर्षक वाले अनुभाग, "चीजें नहीं करना है, और क्यों नहीं करना है" रास्ते के बारे में 3/4 के माध्यम से।

+1

यदि मानक कंटेनर को चीजों की प्रतिलिपि बनाने के लिए 'स्वैप' का उपयोग करने के लिए अनिवार्य किया गया था, तो auto_ptr काम करेगा। और मैं वास्तव में चाहता हूं कि वे थे। सी ++ 0x में, ':: std :: unique_ptr' (जो कि' :: std :: auto_ptr' की तरह है) में भी एक प्रतिलिपि नहीं है, और केवल एक चालक कन्स्ट्रक्टर है, और मानक कंटेनर अनिवार्य हैं अपनी सामग्री को स्थानांतरित करने के लिए चालक कन्स्ट्रक्टर का उपयोग करने के लिए, ताकि आप उनमें से :: :: std :: unique_ptr' स्टोर कर सकें और इसे अपेक्षित रूप से काम कर सकें। – Omnifarious

+0

वास्तव में, एक कंटेनर में 'auto_ptr' का उपयोग करना अवैध है क्योंकि एसटीएल कंटेनर की आवश्यकता है कि उनके सदस्यों के पास" सामान्य "प्रतिलिपि व्यवहार हो। Auto_ptr उस आवश्यकता को पूरा नहीं करता है। –

+1

@ अनन्य: आप shared_ptr को unique_ptr के साथ मिश्रित कर रहे हैं। Shared_ptr एक संदर्भ गिनती स्मार्ट पॉइंटर है, न कि एक चालक अर्थशास्त्र के साथ। –

6
others_.push_back(testptr(new test(other))); 

आप एक std::vector

auto_ptrमें एक auto_ptr पुश करने के लिए एक implic परिभाषित नहीं करता है कोशिश कर रहे हैं यह कन्स्ट्रक्टर की प्रतिलिपि बनाता है और एसटीएल कंटेनर कक्षाओं में एक मान के रूप में संगत नहीं है। StackOverflow: Why is it wrong to use stdauto ptr with stl containers

4

आप auto_ptr के मानक पुस्तकालय कंटेनर नहीं बना सकते, जैसा कि आप यहाँ करने के लिए कोशिश कर रहे हैं:

अधिक जानकारी के लिए इस सवाल का देखें

std::vector<testptr> others_; 

के रूप में वे सही अर्थ विज्ञान नहीं है। आपको साधारण पॉइंटर्स या स्मार्ट पॉइंटर का एक अलग स्वाद, जैसे कि shared_ptr का उपयोग करना होगा।

2

आप शायद std :: unique_ptr या एसटीडी चाहते :: आप एक संकलक इन कि लागू किया गया है (जीसीसी 4.5+) के लिए उपयोग किया है, तो जो auto_ptr का स्थान ले लेगा आगामी C++ 0x मानक से shared_ptr

http://www2.research.att.com/~bs/C++0xFAQ.html#std-unique_ptr http://www2.research.att.com/~bs/C++0xFAQ.html#std-shared_ptr

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