উত্তর:
const_iterator
s আপনাকে যে মানগুলি নির্দেশ করে সেগুলি নিয়মিত করার জন্য আপনাকে সেগুলি পরিবর্তন করতে দেয় iterator
না।
সি ++ তে সমস্ত কিছুর মতো, সর্বদা পছন্দ করুন const
, যদি না নিয়মিত পুনরাবৃত্তিকারীদের ব্যবহার করার কোনও ভাল কারণ না থাকে (যেমন আপনি এই সত্যটি ব্যবহার করতে চান যে তারা const
পয়েন্ট-টু মান পরিবর্তন করে না )।
তাদের বেশিরভাগ স্ব-ব্যাখ্যামূলক হওয়া উচিত। যদি পুনরাবৃত্তিকারী টাইপ টির একটি উপাদানকে নির্দেশ করে, তবে কনস্ট_টিরেটর 'কনস্ট টি' টাইপের একটি উপাদানকে নির্দেশ করে।
এটি মূলত পয়েন্টারের ধরণের সমতুল্য:
T* // A non-const iterator to a non-const element. Corresponds to std::vector<T>::iterator
T* const // A const iterator to a non-const element. Corresponds to const std::vector<T>::iterator
const T* // A non-const iterator to a const element. Corresponds to std::vector<T>::const_iterator
একটি কনট পুনরাবৃত্তকারী সর্বদা একই উপাদানকে নির্দেশ করে, তাই পুনরাবৃত্তকারী নিজেই কনস্ট হয়। তবে যে উপাদানটিকে এটি নির্দেশ করেছে তা কনস্ট হওয়া উচিত নয়, সুতরাং যে উপাদানটিকে এটি নির্দেশ করে তা পরিবর্তন করা যায়। একটি কনস্টিটিউটরেটর এমন একটি পুনরাবৃত্তি যা একটি কনস্টেন্ট উপাদানকে নির্দেশ করে, তাই যখন পুনরুক্তিটি নিজেই আপডেট করা যায় (বর্ধিত বা হ্রাসযুক্ত, উদাহরণস্বরূপ), যে উপাদানটি এটি নির্দেশ করে তা পরিবর্তন করা যায় না।
const iterater
এবং const_iterator
।
Unfortunaty, STL পাত্রে জন্য পদ্ধতি অনেক সময় লাগে iterators পরিবর্তে const_iterators পরামিতি হিসেবে। সুতরাং আপনার যদি কনস্টিটেটর থাকে তবে আপনি বলতে পারবেন না যে "এই পুনরুক্তিকারীটি যে উপাদানটির দিকে ইঙ্গিত করে" তার আগে একটি উপাদান সন্নিবেশ করান "(আমার মতে এ জাতীয় কথা ধারণামূলকভাবে লঙ্ঘন নয়)। আপনি যদি যাইহোক এটি করতে চান, আপনাকে এটি স্ট্যান্ড :: অগ্রিম () বা বুস্ট :: পরবর্তী () ব্যবহার করে একটি নন-কনস্ট্যান্ট পুনরায় রূপান্তর করতে হবে । যেমন। বুস্ট :: পরবর্তী (ধারক.বেগিন (), স্টাড :: দূরত্ব (ধারক.বেগিন (), the_const_iterator_we_ant_to_unconst)) । তাহলে ধারক একটি হয় এসটিডি :: তালিকা , তাহলে সেই কলের জন্য সময় চলমান হবে হে (ঢ) ।
সুতরাং এটি করা "যৌক্তিক" যেখানেই কনস্ট যুক্ত করার সার্বজনীন নিয়মটি এসটিএল পাত্রে চলে আসে তখন সর্বজনীন নয়।
তবে বুস্ট কনটেইনারগুলি কনস্ট_টিরেটর নেয় (উদাঃ বুস্ট :: আনর্ডারড_ম্যাপ :: ইরেজ ())। সুতরাং যখন আপনি বুস্ট পাত্রে ব্যবহার করেন আপনি "কনস্ট আগ্রাসী" হতে পারেন। যাইহোক, কেউ কি জানেন যে কখন বা এসটিএল পাত্রে স্থির হবে?
vector
এবং deque
সমস্ত বিদ্যমান iterators, যা খুবই নয় ঢোকাতে এক উপাদান, অকার্যকর const
। তবে আমি আপনার বক্তব্য দেখতে পাচ্ছি। এই ধরনের ক্রিয়াকলাপগুলি const
কনটেনার-বেকারত্ব দ্বারা সুরক্ষিত থাকে , পুনরাবৃত্তিকারী নয়। এবং আমি অবাক হয়েছি কেন স্ট্যান্ডার্ড কনটেইনার ইন্টারফেসে কনস্ট-টু-ননকনস্ট পুনরায় রূপান্তর ফাংশন নেই।
int const * foo;
int * const foo;
এবং int const * const foo;
তিনটিই বৈধ এবং কার্যকর, প্রতিটি তাদের নিজস্ব উপায়ে। std::vector<int> const bar
দ্বিতীয়টির মতোই হওয়া উচিত, তবে দুর্ভাগ্যক্রমে এটি প্রায়শই তৃতীয়টির মতো হয়। সমস্যার মূল কারণটি হ'ল আমরা বলতে পারি না std::vector<int const> bar;
যখন এর অর্থ কোনও int const *foo;
ভেক্টরের মতো একই প্রভাব পাওয়ার কোনও উপায় নেই ।
ন্যূনতম চলমান উদাহরণ
নন-কনস্ট্যান্ট ইটারেটরগুলি আপনাকে কী নির্দেশ করে তা সংশোধন করার অনুমতি দেয়:
std::vector<int> v{0};
std::vector<int>::iterator it = v.begin();
*it = 1;
assert(v[0] == 1);
কনস্টেট পুনরাবৃত্তিকারীরা এটি করে না:
const std::vector<int> v{0};
std::vector<int>::const_iterator cit = v.begin();
// Compile time error: cannot modify container with const_iterator.
//*cit = 1;
উপরে দেখানো হিসাবে, v.begin()
হয় const
ওভারলোড, এবং আয় হয় iterator
বা const_iterator
ধারক ভেরিয়েবলের const-অন্তরীপ উপর ভিত্তি করে:
একটি সাধারণ ক্ষেত্রে যেখানে const_iterator
পপ আপ হয় this
কোনও const
পদ্ধতির অভ্যন্তরে ব্যবহৃত হয় :
class C {
public:
std::vector<int> v;
void f() const {
std::vector<int>::const_iterator it = this->v.begin();
}
void g(std::vector<int>::const_iterator& it) {}
};
const
তোলে this
যার ফলে const, this->v
const।
আপনি এটির সাথে সাধারণত এটি ভুলে যেতে পারেন auto
, তবে আপনি যদি এই পুনরুক্তিগুলি চারপাশে পাস করতে শুরু করেন তবে আপনাকে পদ্ধতি স্বাক্ষরের জন্য তাদের সম্পর্কে ভাবতে হবে।
অনেকটা কনস্ট্যান্ড এবং নন-কনস্টের মতোই আপনি নন-কনস্ট থেকে কনস্টে সহজে রূপান্তর করতে পারেন তবে অন্য উপায়ে নয়:
std::vector<int> v{0};
std::vector<int>::iterator it = v.begin();
// non-const to const.
std::vector<int>::const_iterator cit = it;
// Compile time error: cannot modify container with const_iterator.
//*cit = 1;
// Compile time error: no conversion from const to no-const.
//it = ci1;
কোনটি ব্যবহার করবেন: বনামের সাথে const int
সাদৃশ্যযুক্ত int
: যখনই আপনি তাদের ব্যবহার করতে পারেন কনস্টেটের পুনরাবৃত্তিগুলি পছন্দ করুন (যখন আপনার সাথে ধারকটি সংশোধন করার প্রয়োজন হবে না), কোনও সংশোধন না করে পড়ার আপনার উদ্দেশ্যটি আরও ভাল করে ডকুমেন্ট করতে।
(যেমন অন্যেরা বলেছেন) কনস্টেটাইটারেটর আপনাকে যে উপাদানগুলিতে এটি নির্দেশ করে তা সংশোধন করার অনুমতি দেয় না, এটি কনস্টের ক্লাস পদ্ধতিগুলির মধ্যে দরকারী। এটি আপনাকে আপনার অভিপ্রায় প্রকাশ করার অনুমতি দেয়।
ঠিক আছে আমাকে ধীরে ধীরে পুনরাবৃত্তকারী ব্যবহার না করে প্রথমে খুব সাধারণ উদাহরণ দিয়ে এটি ব্যাখ্যা করতে পারি বিবেচনা করুন আমাদের কাছে এলোমেলো পূর্ণসংখ্যা সংগ্রহ "এলোমেলো ডেটা" রয়েছে
for(vector<int>::iterator i = randomData.begin() ; i != randomData.end() ; ++i)*i = 0;
for(vector<int>::const_iterator i = randomData.begin() ; i!= randomData.end() ; ++i)cout << *i;
সংগ্রহের অভ্যন্তরে ডেটা লেখার / সম্পাদনার জন্য দেখা যায় সাধারণ পুনরাবৃত্তি ব্যবহৃত হয় তবে পড়ার উদ্দেশ্যে ধ্রুব পুনরুক্তি ব্যবহৃত হয়। আপনি যদি লুপের জন্য প্রথমে ধ্রুবক পুনরায় ব্যবহার করার চেষ্টা করেন তবে আপনি ত্রুটি পাবেন। একটি থাম্ব নিয়ম হিসাবে সংগ্রহের ভিতরে ডেটা পড়তে ধ্রুব পুনরুক্তি ব্যবহার করুন।