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


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.