সরানো পাত্রে পুনরায় ব্যবহার করছেন?


85

সরানো পাত্রে পুনরায় ব্যবহার করার সঠিক উপায় কী?

std::vector<int> container;
container.push_back(1);
auto container2 = std::move(container);

// ver1: Do nothing
//container2.clear(); // ver2: "Reset"
container = std::vector<int>() // ver3: Reinitialize

container.push_back(2);
assert(container.size() == 1 && container.front() == 2);

আমি সি ++ 0 এক্স স্ট্যান্ডার্ড খসড়াটিতে যা পড়েছি তা থেকে; ver3 হ'ল সঠিক উপায় বলে মনে হচ্ছে, যেহেতু সরানোর পরে কোনও বস্তু একটিতে থাকে

"অন্যথায় নির্দিষ্ট না করাতে এ জাতীয় স্থানান্তরিত অবজেক্টগুলি বৈধ তবে অনির্ধারিত অবস্থায় স্থাপন করা হবে।"

এটি "অন্যথায় নির্দিষ্ট করা" যেখানে এমন কোনও নজির আমি পাইনি instance

যদিও আমি ভার্3টিকে কিছুটা চক্রাকারে খুঁজে পেয়েছি এবং ভেরি 3 আরও পছন্দসই পছন্দ করবে যদিও ভেক 3 কিছু অতিরিক্ত অপ্টিমাইজেশনের অনুমতি দিতে পারে তবে অন্যদিকে সহজেই ভুলগুলি হতে পারে।

আমার ধারণা সঠিক?


4
আপনি কেবল কল করতে পারেন clear, কারণ এতে কোনও পূর্বশর্ত নেই (এবং এভাবে বস্তুর অবস্থার উপর কোনও নির্ভরতা নেই)।
নিকোল বোলাস

@ নিকোল: আসুন আমরা বলি যে একটি std::vectorবাস্তবায়ন ছিল যা এটির আকারের একটি পয়েন্টার সঞ্চার করে (নির্বোধ বলে মনে হয় তবে আইনী বলে মনে হয়)। সেই ভেক্টর থেকে সরে যাওয়ার ফলে পয়েন্টারটি NULL ছেড়ে যেতে পারে, এর পরে clearব্যর্থ হবে। operator=ব্যর্থ হতে পারে।
বেন ভয়েগট

10
@ বেন: আমি মনে করি এটি "বৈধ তবে অনির্ধারিত" এর "বৈধ" অংশটি লঙ্ঘন করবে।
iljarn

4
@ এল্ডজার্ন: আমি ভেবেছিলাম এর অর্থ হ'ল এটি ধ্বংসকারী চালানো নিরাপদ।
বেন ভয়েগ্ট

আমার মনে হয় প্রশ্নটি "বৈধ" কি?
রোন্যাগ

উত্তর:


98

"বৈধ তবে অনির্দিষ্ট অবস্থা" এর অনুচ্ছেদের 17.3.26 ধারা থেকে:

কোনও অবজেক্টের অবস্থা যা নির্দিষ্ট না করা ব্যতীত অবজেক্টের আক্রমণকারীদের পূরণ হয় এবং বস্তুর ক্রিয়াকলাপগুলি তার ধরণের জন্য নির্দিষ্ট হিসাবে আচরণ করে [উদাহরণস্বরূপ: যদি কোনও xপ্রকারের অবজেক্ট std::vector<int>বৈধ তবে অনির্ধারিত অবস্থায় থাকে তবে x.empty()তাকে নিঃশর্ত x.front()বলা যেতে পারে এবং বলা যেতে পারে শুধুমাত্র যদি x.empty()আয় মিথ্যা। এর উদাহরণ]

সুতরাং, অবজেক্টটি লাইভ। আপনি এমন কোনও অপারেশন করতে পারেন যার জন্য পূর্ব শর্তের প্রয়োজন নেই (যদি আপনি পূর্ব শর্তটি যাচাই না করেন)।

clearউদাহরণস্বরূপ, কোনও পূর্বশর্ত নেই। এবং এটি বস্তুটি একটি পরিচিত অবস্থায় ফিরিয়ে দেবে। সুতরাং এটি পরিষ্কার করুন এবং এটি সাধারণ হিসাবে ব্যবহার করুন।


স্ট্যান্ডার্ড :: ভেক্টর পদ্ধতিগুলির জন্য আমি "পূর্বশর্ত" সম্পর্কে কোথায় স্ট্যান্ডার্ডে পড়তে পারি?
রোন্যাগ

4
@ronag: .223.2 এ টেবিল রয়েছে যেখানে সেগুলি তালিকাভুক্ত রয়েছে।
গ্রিজলি

4
আমি নিম্নলিখিতটি খুঁজে পেয়েছি যা আকর্ষণীয়, ওপেন- std.org/jtc1/sc22/wg21/docs/papers/2011/n3241.html , তারা লিখেছেন "পাত্রে 'খালি চেয়ে খালি" হতে পারে "।
রোন্যাগ

4
@ অ্যারন্যাগ: ১) ধারকটি যদি বৈধ অবস্থায় থাকে তবে কলিংটি clearবৈধ। 2) ধারক যদিও ছিল একটি অনির্দিষ্ট অবস্থায়, কলিং clearরাখে একটি নির্দিষ্ট দশায় ধারক কারণ এটি মানক (§23.2.3 টেবিল 100) মধ্যে postconditions বাধ্যতামূলক করেছে। std::vector<T>একটি শ্রেণীর আক্রমণকারী রয়েছে যা push_back()সর্বদা বৈধ থাকে (যতক্ষণ Tথাকে CopyInsertable)।
iljarn

4
@ অরনগ: ওপেন-std.org/jtc1/sc22/wg21/docs/papers/2011/n3241.html "খালি চেয়ে খালি" উদ্ধৃতি সম্পর্কে জাতীয় সংস্থা একটি মন্তব্য উদ্ধৃত করে ছিল। জাতীয় সংস্থার মন্তব্যটি ভুল ছিল। N3241 এমন একটি রাজ্যের প্রস্তাব দেয়নি। যদি একটি স্ট্যান্ড :: কনটেইনার বাস্তবায়নের কোনও "খালি তুলনায় খাঁটি" রাজ্য থাকে যা কোনও স্থানান্তর থেকে আসে, তবে সেই রাষ্ট্রটি অবশ্যই একটি বৈধ রাষ্ট্র হতে হবে (অর্থাত্ that বস্তুটির সাথে আপনি যে কোনও পূর্বশর্ত প্রয়োজন না এমন কিছু করতে পারেন)।
হাওয়ার্ড হিনান্ট

11

অবজেক্টটি বৈধ, তবে অপরিজ্ঞাত অবস্থায় থাকার অর্থ মূলত এর অর্থ হ'ল যখন অবজেক্টের সঠিক অবস্থার গ্যারান্টি নেই তবে এটি বৈধ এবং যেমন সদস্য ফাংশনগুলি (বা অ-সদস্য ফাংশন) যতক্ষণ না তারা নির্ভর করে না কাজ করার গ্যারান্টিযুক্ত একটি নির্দিষ্ট রাষ্ট্র থাকার বস্তুর উপর।

clear()সদস্য ফাংশন বস্তু এবং সেইজন্য বস্তু থেকে সরানো অন বলা যেতে পারে (তুলনায় এটি বৈধ, অবশ্যই অন্যান্য) রাজ্যের কোন পূর্বশর্ত হয়েছে। অন্যদিকে উদাহরণস্বরূপ front()কনটেইনারটি খালি নয়, এবং তাই এটি কল করা যায় না, কারণ এটি খালি না থাকার গ্যারান্টি নেই depends

সুতরাং ver2 এবং ver3 উভয়ই ঠিক থাকতে হবে।


একটি ভেক্টর সর্বদা খালি থাকবে, তবে এটি সাধারণ ক্ষেত্রে সত্য নয়, (IE অ্যারে)
মাকিং হাঁস

"একটি ভেক্টর সর্বদা খালি থাকবে", আপনি এটির ভিত্তি কী করবেন?
রোন্যাগ

4
@ অ্যারন্যাগ: আমি অবশ্যই ver2 এবং ver3 বলতে চাইছিলাম (যেমন পাঠ্য থেকে স্পষ্ট হওয়া উচিত, টাইপোটি ঠিক করা হয়েছিল
গ্রিজলি

মজার বিষয় হল, পূর্বশর্তগুলি front()কেবলমাত্র জন্য বর্ণিত হয় std::array, এবং এমনকি টেবিলে নেই।
বেন ভয়েগ্ট

4
@Ben: §23.2.3 টেবিল 100 বলছে যে কর্মক্ষম শব্দার্থবিদ্যা front()হয় *a.begin(), §23.2.1 / 6 বলে " তাহলে ধারক খালি, তারপরbegin() == end() ", এবং §24.2.1 / 5 বলে " গ্রন্থাগার যে past- কখনো অনুমান শেষ মান dereferenceable হয়। "। ফলস্বরূপ আমি মনে করি পূর্বের শর্তগুলি front()অনুমান করা যায়, যদিও এটি অবশ্যই আরও স্পষ্ট করে দেওয়া যেতে পারে।
iljarn

-8

আমি মনে করি না আপনি সরানো-থেকে কোনও বস্তু (এটি ধ্বংস ব্যতীত) দিয়ে কিছুই করতে পারবেন না।

আপনি কি swapপরিবর্তে ব্যবহার করতে পারবেন না , চলার সমস্ত সুবিধা পেতে কিন্তু ধারকটি একটি পরিচিত অবস্থায় রেখে যান?


+1 অদলবদল একটি ভাল ধারণা, যদিও এটি সব ক্ষেত্রে কার্যকর হবে না, যেমন অটো ব্যবহার করে কাজ হবে না। হতে পারে একটি সেফ_মোভ, যা অভ্যন্তরীণভাবে অদলবদল ব্যবহার করে একটি ধারণা হতে পারে?
রোন্যাগ

4
এটি একটি লাইভ অবজেক্ট এবং আপনি এমন কোনও ফাংশন ব্যবহার করতে পারেন যা পূর্বশর্ত না রয়েছে (
আক্রমণকারীদের বাদে

এর জন্য প্রাথমিক টেম্পলেটটিতে std::swap2 টি সরানো অ্যাসাইনমেন্ট রয়েছে, সেই সাথে অ্যাসাইনমেন্টগুলির লক্ষ্যগুলি স্থানান্তরিত থেকে মানগুলি স্থানান্তরিত হচ্ছে। এটি আমার কাছে "একটি স্থানান্তরিত বস্তুর কাছে কিছু করা" হিসাবে গণ্য হয়েছে
কালেথ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.