2012-01-06 8 views
5

unique_ptr का एक कंटेनर थोड़ा समझ में आता है: आप इसे प्रारंभकर्ता सूचियों के साथ उपयोग नहीं कर सकते हैं और मैं कंटेनर (नीचे कामकाज) के माध्यम से पुन: प्रयास करने में विफल रहा। क्या मैं कुछ गलत समझ रहा हूँ? या unique_ptr और एसटीएल कंटेनर का उपयोग करने के लिए यह कब समझ में आता है?एसटीएल कंटेनर के साथ unique_ptr का उपयोग करने के लिए यह समझ में आता है? (सी ++ 11)

उत्तर

14
for (auto i : v5) { 
    i->go(); 
} 

for (auto& i : v5) { // note 'auto&' 
    i->go(); 
} 

वरना आप वर्तमान तत्व नकल करने की कोशिश करेंगे होना चाहिए।

इसके अलावा, आप, ऐसे ही एक प्रारंभकर्ता सूची का उपयोग नहीं कर सकते क्योंकि std::unique_ptr और std::shared_ptr की कंस्ट्रक्टर्स explicit चिह्नित कर रहे हैं। क्योंकि अन्यथा आप स्मृति (अगर बाद में निर्माताओं की एक फेंकता है, पूर्व वाले अभी तक स्मार्ट संकेत करने के लिए बाध्य नहीं कर रहे हैं रिसाव हो सकता है

#include <iterator> // make_move_iterator, begin, end 

template<class T> 
std::unique_ptr<T> make_unique(){ // naive implementation 
    return std::unique_ptr<T>(new T()); 
} 

std::unique_ptr<Base> v1_init_arr[] = { 
    make_unique<Derived>(), make_unique<Derived>(), make_unique<Derived>() 
}; 

// these two are only for clarity 
auto first = std::make_move_iterator(std::begin(v1_init_arr)); 
auto last = std::make_move_iterator(std::end(v1_init_arr)); 
std::vector<std::unique_ptr<Base>> v1(first, last); 

std::vector<std::shared_ptr<Base>> v2 = { 
    std::make_shared<Derived>(), 
    std::make_shared<Derived>(), 
    std::make_shared<Derived>() 
}; 

और यह एक अच्छी बात ™ है,: आप कुछ इस तरह करने की जरूरत है)। unique_ptr के लिए टिप-टोइंग आवश्यक है, क्योंकि प्रारंभकर्ता सूचियां उनके तर्कों की प्रतिलिपि बनाती हैं, और unique_ptr एस कॉपी करने योग्य नहीं हैं, इसलिए आपको कोई समस्या होगी।


उसने कहा, मैं अपनी परियोजनाओं में से किसी एक में लोडर के शब्दकोश के लिए std::map<std::string, std::unique_ptr<LoaderBase>> का उपयोग करता हूं।

+1

'वेक्टर > v1 = {make_unique (), make_unique (), make_unique ()};' <- आपको लगता है कि परीक्षण किया? –

+0

जैसा कि @ बेंजामिन बताता है, प्रारंभकर्ता सूचियां परिभाषाओं द्वारा प्रतियां बनाते हैं, इसलिए इन्हें केवल चाल-वस्तुओं के साथ उपयोग नहीं किया जा सकता है। – ildjarn

+0

@ बेंजामिन: स्वीकार्य रूप से, नहीं, क्योंकि मेरे पास वर्तमान में कोई कंपाइलर उपलब्ध नहीं है जो प्रारंभिक सूचियों का समर्थन करता है।मुझे नहीं पता कि समस्या क्या हो सकती है? – Xeo

1

unique_ptr एसटीएल कंटेनर में समझ में आता है जब कंटेनर ऑब्जेक्ट रखता है जिसे कॉपी नहीं किया जा सकता है। या यदि उन्हें कॉपी करने के लिए महंगा या बस गलत है।

आप अपने

vector<Base*> v3 = { new Derived, new Derived, new Derived }; 

रूप में एक ही कार्यक्षमता प्राप्त लेकिन स्मृति के बिना लीक कि v3 आमंत्रित कर रही है।

+1

या जब आपको पॉलिमॉर्फिक व्यवहार की आवश्यकता होती है। – ildjarn

+0

आप सी ++ 11 कंटेनरों में अवांछनीय वस्तुओं (जैसे 'unique_ptr') डाल सकते हैं; हालांकि कुछ कंटेनर की आवश्यकता है कि वे जंगम हैं। –

1

आप वास्तव में std::unique_ptr<T> का उपयोग कर बिना किसी समस्या के कंटेनर को फिर से सक्रिय कर सकते हैं ... आपको या तो अद्वितीय सूचक के संदर्भ (यानी एक प्रति नहीं) तक पहुंचने की आवश्यकता है, या आपको वास्तव में एक इटरेटर-प्रकार का उपयोग करने की आवश्यकता है कंटेनर। आपके मामले में यह vector<unique_ptr<Base>>::iterator या vector<unique_ptr<Base>>::const_iterator जैसा कुछ होगा।

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

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