मैं वेक्टर में एक यूनिक_प्टर को क्यों नहीं पुश कर सकता / सकती हूं?


217

इस कार्यक्रम में क्या गलत है?

#include <memory>
#include <vector>

int main()
{
    std::vector<std::unique_ptr<int>> vec;

    int x(1);
    std::unique_ptr<int> ptr2x(&x);
    vec.push_back(ptr2x); //This tiny command has a vicious error.

    return 0;
}

त्रुटि:

In file included from c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/mingw32/bits/c++allocator.h:34:0,
                 from c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/allocator.h:48,
                 from c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/memory:64,
                 from main.cpp:6:
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h: In member function 'void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp = std::unique_ptr<int>, _Tp* = std::unique_ptr<int>*]':
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/stl_vector.h:745:6:   instantiated from 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::unique_ptr<int>, _Alloc = std::allocator<std::unique_ptr<int> >, value_type = std::unique_ptr<int>]'
main.cpp:16:21:   instantiated from here
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h:207:7: error: deleted function 'std::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = int, _Tp_Deleter = std::default_delete<int>, std::unique_ptr<_Tp, _Tp_Deleter> = std::unique_ptr<int>]'
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/ext/new_allocator.h:105:9: error: used here
In file included from c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/vector:69:0,
                 from main.cpp:7:
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h: In member function 'void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const std::unique_ptr<int>&}, _Tp = std::unique_ptr<int>, _Alloc = std::allocator<std::unique_ptr<int> >, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<std::unique_ptr<int>*, std::vector<std::unique_ptr<int> > >, typename std::vector<_Tp, _Alloc>::_Base::_Tp_alloc_type::pointer = std::unique_ptr<int>*]':
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/stl_vector.h:749:4:   instantiated from 'void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = std::unique_ptr<int>, _Alloc = std::allocator<std::unique_ptr<int> >, value_type = std::unique_ptr<int>]'
main.cpp:16:21:   instantiated from here
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/unique_ptr.h:207:7: error: deleted function 'std::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = int, _Tp_Deleter = std::default_delete<int>, std::unique_ptr<_Tp, _Tp_Deleter> = std::unique_ptr<int>]'
c:\mingw\bin\../lib/gcc/mingw32/4.5.0/include/c++/bits/vector.tcc:314:4: error: used here

जवाबों:


328

आपको इसे स्थानांतरित करने की आवश्यकता है unique_ptr:

vec.push_back(std::move(ptr2x));

unique_ptrगारंटी देता है कि एक एकल unique_ptrकंटेनर में आयोजित सूचक का स्वामित्व है। इसका मतलब है कि आप इसकी प्रतियां नहीं बना सकते unique_ptr(क्योंकि तब दो unique_ptrएस का स्वामित्व होगा), इसलिए आप इसे स्थानांतरित कर सकते हैं।

हालाँकि, नोट करें कि आपका वर्तमान उपयोग unique_ptrगलत है। आप इसका उपयोग स्थानीय चर के लिए सूचक को प्रबंधित करने के लिए नहीं कर सकते। स्थानीय चर का जीवनकाल स्वचालित रूप से प्रबंधित होता है: ब्लॉक समाप्त होने पर स्थानीय चर नष्ट हो जाते हैं (जैसे, जब फ़ंक्शन वापस आता है, इस मामले में)। आपको ऑब्जेक्ट को गतिशील रूप से आवंटित करने की आवश्यकता है:

std::unique_ptr<int> ptr(new int(1));

12
चूंकि केवल एक ही हो सकता है, एक को सीधे वेक्टर के लिए एक अस्थायी पास करने में सक्षम होना चाहिए vec.push_back(std::unique_ptr<int>(new int(1)));:। unique_ptrएक कस्टम डिलेटर (जो कुछ भी नहीं करता है) का उपयोग कर सकता है, लेकिन फिर किसी को इस बात का ध्यान रखना चाहिए कि स्कोप के अंत में लोकल वेरिएबल का पता अमान्य हो जाता है।
अंकलबींस

18
एक अन्य विकल्प का उपयोग करना है emplace_back। जैसेvec.emplace_back(new int(1));
deft_code

75
@deft_code: नहीं, यह सुरक्षित नहीं है। emplace_backआपरेशन फेंक कर सकते हैं, और अगर यह होता है, गतिशील रूप से आवंटित intलीक कर दिया जाएगा। अंगूठे का नियम यह है कि रिसाव से बचने के लिए सभी गतिशील आवंटन एक नामित स्मार्ट पॉइंटर के स्वामित्व में होने चाहिए।
जेम्स मैकनेलिस

8
make_sared () एक साझा_प्रात लौटाता है, एक यूनिक_प्रट नहीं। दुर्भाग्य से, C ++ 11 में कोई make_unique () नहीं है; एक दुर्भाग्यपूर्ण चूक जो उम्मीद है कि C ++ 14 में तय की जाएगी
cdmh

29
@FKaria make_unique () का अर्थ होगा कि newकभी भी सीधे आमंत्रित करने की आवश्यकता नहीं है, जो प्रोग्रामर की मानसिकता को बदलता है और मेमोरी लीक से बचा जाता है। "नए से बचें और हटाएं" जैसी सलाह तो मेयर्स / अलेक्जेंड्रेस्कु / सटर की किताब के अगले संस्करण में दिखाई दे सकती है :)
cdmh

24

std :: unique_ptr का कोई प्रतिलिपि निर्माता नहीं है। आप एक उदाहरण बनाते हैं और फिर std :: वेक्टर को उस उदाहरण को कॉपी करने के लिए पूछते हैं जो आरंभीकरण के दौरान होता है।

error: deleted function 'std::unique_ptr<_Tp, _Tp_Deleter>::uniqu
e_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = int, _Tp_D
eleter = std::default_delete<int>, std::unique_ptr<_Tp, _Tp_Deleter> =
 std::unique_ptr<int>]'

कक्षा MoveConstructible और MoveAssignable की आवश्यकताओं को पूरा करती है, लेकिन CopyConstructible या CopyAssignable की आवश्यकताओं को नहीं।

निम्नलिखित नए इमल्स कॉल के साथ काम करता है ।

std::vector< std::unique_ptr< int > > vec;
vec.emplace_back( new int( 1984 ) );

आगे पढ़ने के लिए मानक पुस्तकालय कंटेनरों के साथ unique_ptr का उपयोग करें देखें ।


5
इस टिप्पणी को देखें - emplace_x()स्मार्ट पॉइंटर्स का उपयोग करते समय फ़ंक्शन का उपयोग करना असुरक्षित है।
Qix - मोनासा ने

तो एक unique_ptr को वेक्टर में स्टोर करने का सबसे अच्छा तरीका क्या है? जैसा कि मैंने परीक्षण किया यह कच्चे सूचक की तुलना में बहुत धीमा है।
user2189731
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.