আমি কেন কোনও ভেক্টরে একটি অনন্য_প্টরকে ধাক্কা দিতে পারি না?


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));
— ডিফ্ট_কোড

75
@ ডিফ্ট_কোড: না, এটি নিরাপদ নয়। emplace_backঅপারেশন নিক্ষেপ করতে পারেন, এবং যদি এটা করে, পরিবর্তনশীল বরাদ্দ intফাঁস করা হবে না। থাম্বের নিয়মটি হ'ল সমস্ত গতিশীল বরাদ্দগুলি ফুটো এড়াতে একটি নামী স্মার্ট পয়েন্টারের মালিকানাধীন হওয়া উচিত।
— জেমস ম্যাকনেলিস

8
Make_shared () একটি শেয়ার করা_পিটার প্রদান করে, কোনও অনন্য_পিটার নয়। দুর্ভাগ্যক্রমে, সি ++ 11 এ কোনও মেক-ইউনিক () নেই; দুর্ভাগ্যজনক একটি বাদ যা আশা করা যায় যে C ++ 14
— সিডিএমএইচ

29
@ এফকারিয়া মেক_উনিক () এর অর্থ হ'ল কখনই সরাসরি ডাকা হবে newনা, যা প্রোগ্রামারের মানসিকতার পরিবর্তন করে এবং মেমরি ফাঁসকে এড়িয়ে যায় (উল্লেখযোগ্যভাবে হ্রাস করে)। "নতুন এড়ানো এবং মুছুন" এর মতো
— পরামর্শগুলি

24

std :: অনন্য_পিটারের কোনও অনুলিপি নির্মাণকারী নেই। আপনি একটি উদাহরণ তৈরি করেন এবং তারপরে 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>]'

শ্রেণিটি মুভকনস্ট্রাক্টেবল এবং মুভএইসাইনেবলের প্রয়োজনীয়তাগুলি পূরণ করে তবে কপিরাইটস্ট্রাক্টিবল বা কপিরএসিগনেবলের প্রয়োজনীয়তা নয়।

নিম্নলিখিত নতুন এম্বেস কলগুলির সাথে কাজ করে।

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

আরও পড়ার জন্য স্ট্যান্ডার্ড লাইব্রেরি পাত্রে ইউনিক_পিটার ব্যবহার করে দেখুন ।


5
এই মন্তব্যটি দেখুন - emplace_x()স্মার্ট পয়েন্টার ব্যবহার করার সময় ফাংশনগুলি অনিরাপদ।
— কিউক্স - মনিকা

তাহলে কোনও ভিন্টারে কোনও অনন্য_পাত্র সংরক্ষণ করার সর্বোত্তম উপায় কী? আমি পরীক্ষিত হিসাবে এটি কাঁচা পয়েন্টারের সাথে তুলনা করে অত্যন্ত ধীর।
— ব্যবহারকারী 2189731
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.