c++ - tutorial - সি++ প্রোগ্রামিং বই ডাউনলোড




সি++ 11 এ অ সদস্যের শুরু এবং শেষ ফাংশন কেন ব্যবহার করবেন? (4)

অ-সদস্য ফাংশন স্ট্যান্ডার্ড কনটেইনারগুলির জন্য কোনও সুবিধা প্রদান করে না, এটি ব্যবহার করে আরো সামঞ্জস্যপূর্ণ এবং নমনীয় শৈলী প্রয়োগ করে। আপনি যদি কোনও সময়ে একটি বিদ্যমান অ-স্টেড ধারক শ্রেণি প্রসারিত করতে চান তবে আপনি বিদ্যমান শ্রেণীটির সংজ্ঞা পরিবর্তনের পরিবর্তে বিনামূল্যে ফাংশনগুলির ওভারলোডগুলি সংজ্ঞায়িত করতে চান। সুতরাং non-std কন্টেনারগুলির জন্য তারা খুব দরকারী এবং সর্বদা বিনামূল্যে ফাংশনগুলি ব্যবহার করে আপনার কোডকে আরও বেশি নমনীয় করে তোলে যাতে আপনি স্ট্যাড কনটেইনারটি অ-স্টেড ধারক দ্বারা আরো সহজে প্রতিস্থাপন করতে পারেন এবং অন্তর্নিহিত ধারক প্রকারটি আপনার কোডের জন্য আরও স্বচ্ছ হয় ধারক বাস্তবায়ন অনেক ব্যাপক বৈচিত্র্য সমর্থন করে।

কিন্তু অবশ্যই এই সবসময় সঠিকভাবে ওজন করা আছে এবং বিমূর্তকরণ ভাল হয় না হয়। ফ্রি ফাংশনগুলি ব্যবহার করা যদিও একটি অতিরিক্ত-বিমূর্ততা নয় তবে তা C ++ 03 কোডের সাথে সামঞ্জস্য বিচ্ছিন্ন করে, যা C ++ 11 এর এই অল্প বয়সেও আপনার জন্য একটি সমস্যা হতে পারে।

প্রতিটি মান কন্টেইনারের একটি ধারক এবং end পদ্ধতি রয়েছে যার জন্য এটি কন্টেইনারের জন্য ইটারারেটর ফেরত পাঠানো হয়। যাইহোক, সি ++ 11 স্পষ্টভাবে std::begin std::end এবং std::end নামে পরিচিত ফাংশন চালু করেছে যা begin এবং end সদস্য ফাংশনগুলিকে কল করে। সুতরাং, লেখার পরিবর্তে

auto i = v.begin();
auto e = v.end();

আপনি লিখতে চাই

using std::begin;
using std::end;
auto i = begin(v);
auto e = end(v);

তার কথোপকথনে, মডার্ন সি ++ রাইটিং , হেরব Sutter বলছেন যে আপনি এখন একটি কন্টেইনার জন্য শুরু বা শেষ ইটারারেটর চান যখন আপনি এখন বিনামূল্যে ফাংশন ব্যবহার করা উচিত। যাইহোক, তিনি কেন আপনি চান করতে হবে বিস্তারিত জানায় না। কোডটি দেখে, এটি আপনাকে এক অক্ষরের সব সংরক্ষণ করে। সুতরাং, যতক্ষণ পর্যন্ত স্ট্যান্ডার্ড কন্টেনারগুলি চলে যায়, বিনামূল্যে ফাংশন সম্পূর্ণরূপে নিরর্থক বলে মনে হয়। হার্ব শটার নির্দেশ করে যে অ-স্ট্যান্ডার্ড কন্টেইনারগুলির জন্য বেনিফিট ছিল, কিন্তু আবার, তিনি বিস্তারিতভাবে যাননি।

সুতরাং, প্রশ্নটি হচ্ছে std::begin ফ্রি এবং ফাংশন ফাংশনগুলি ঠিক কীভাবে তাদের সংশ্লিষ্ট সদস্য ফাংশন সংস্করণগুলি কল করার পরেও না এবং কেন আপনি তাদের ব্যবহার করতে চান?


আপনার প্রশ্নের উত্তর দিতে, বিনামূল্যে ফাংশন শুরু () এবং শেষ () ডিফল্টভাবে কনটেইনারের সদস্য .begin () এবং .end () ফাংশন কল করার চেয়ে বেশি কিছু করে না। <iterator> , আপনি <vector> , <list> , ইত্যাদির মতো কোনও স্ট্যান্ডার্ড ধারক ব্যবহার করার সময় স্বয়ংক্রিয়ভাবে অন্তর্ভুক্ত হয়েছেন, আপনি পাবেন:

template< class C > 
auto begin( C& c ) -> decltype(c.begin());
template< class C > 
auto begin( const C& c ) -> decltype(c.begin()); 

আপনার দ্বিতীয় অংশটি হল কেন ফ্রী ফাংশনগুলি পছন্দ করে যদি তারা যা করে তা সদস্য সদস্যদের ফাংশনগুলিকে কল করুন। যে সত্যিই বস্তুর v আপনার উদাহরণ কোড হয় ধরনের উপর নির্ভর করে। যদি v এর ধরনটি স্ট্যান্ডার্ড ধারক প্রকারের মতো থাকে তবে vector<T> v; আপনি বিনামূল্যে বা সদস্য ফাংশন ব্যবহার করলে তা কোন ব্যাপার না, তারা একই জিনিস করে। যদি আপনার অবজেক্ট v আরও জেনেরিক হয়, নিম্নলিখিত কোডের মতো:

template <class T>
void foo(T& v) {
  auto i = v.begin();     
  auto e = v.end(); 
  for(; i != e; i++) { /* .. do something with i .. */ } 
}

তারপর সদস্য ফাংশন ব্যবহার করে টি = সি অ্যারে, সি স্ট্রিং, enums ইত্যাদি জন্য আপনার কোড বিরতি। অ-সদস্য ফাংশন ব্যবহার করে, আপনি একটি সহজতর প্রসারিত করতে পারেন যে একটি সাধারণ জেনারেট ইন্টারফেস বিজ্ঞাপন। ফ্রি ফাংশন ইন্টারফেস ব্যবহার করে:

template <class T>
void foo(T& v) {
  auto i = begin(v);     
  auto e = end(v); 
  for(; i != e; i++) { /* .. do something with i .. */ } 
}

কোডটি এখন টি = সি অ্যারে এবং সি স্ট্রিংগুলির সাথে কাজ করে। এখন অ্যাডাপ্টার কোড একটি ছোট পরিমাণ লেখা:

enum class color { RED, GREEN, BLUE };
static color colors[]  = { color::RED, color::GREEN, color::BLUE };
color* begin(const color& c) { return begin(colors); }
color* end(const color& c)   { return end(colors); }

আমরা আপনার কোড খুব কার্যকর enums সঙ্গে সামঞ্জস্যপূর্ণ পেতে পারেন। আমার মনে হয় হেরব এর মূল বিষয়টি হল যে ফাংশনগুলি ব্যবহার করে সদস্য ফাংশনগুলি ব্যবহার করা সহজ, এবং এটি আপনার কোডটিকে সি ক্রম প্রকারের সাথে পশ্চাদপট সামঞ্জস্য দেয় এবং অ-স্টল ক্রম প্রকারের (এবং ভবিষ্যত-স্টাইল প্রকারের!) সহ আরও সামঞ্জস্যপূর্ণতা দেয়। অন্যান্য ডেভেলপারদের কম খরচে।


আপনি কিভাবে একটি c-array এ .begin() এবং .end() কল .begin() ?

ফ্রী-ফাংশনগুলি আরও জেনেরিক প্রোগ্রামিংয়ের জন্য অনুমতি দেয় কারণ তারা পরে সংযোজন করা যেতে পারে এমন একটি ডেটা-স্ট্রাকচারে যোগ করা যেতে পারে।


begin এবং end ফাংশন ব্যবহার করে সংকেত এক স্তর যোগ করে। সাধারণত আরো নমনীয়তা অনুমতি দেওয়া হয়।

এই ক্ষেত্রে আমি কয়েক ব্যবহার চিন্তা করতে পারেন।

সবচেয়ে সুস্পষ্ট ব্যবহার সি-অ্যারে (সি পয়েন্টার নয়)।

অন্য একটি যখন একটি অ- .begin() কন্টেইনারে একটি স্ট্যান্ডার্ড অ্যালগরিদম ব্যবহার করার চেষ্টা করা হয় (অর্থাৎ ধারক একটি .begin() পদ্ধতি অনুপস্থিত)। আপনি কনটেইনার ঠিক ঠিক করতে পারবেন না বলে মনে হচ্ছে, পরবর্তী সেরা বিকল্পটি begin ফাংশন ওভারলোড করা হয়। Herb আপনি সবসময় আপনার কোড অভিন্নতা এবং সামঞ্জস্য উন্নীত করার জন্য begin ফাংশন ব্যবহার সুপারিশ করা হয়। পরিবর্তে কোন কন্টেইনার সমর্থন পদ্ধতি begin এবং যা ফাংশন begin প্রয়োজন মনে রাখা হচ্ছে।

সরাইয়া হিসাবে, পরবর্তী সি ++ পুনর্বিবেচনা D' sseudo- সদস্য নোট অনুলিপি করা উচিত। যদি a.foo(b,c,d) সংজ্ঞায়িত না হয় তবে এটি foo(a,b,c,d) । এটি একটি সামান্য সিনট্যাক্টিক চিনি যা আমাদের গরীব মানুষকে সাহায্য করে, যারা ক্রিয়া ক্রম অনুসারে বিষয় পছন্দ করে।





c++11