বিশেষত লুপগুলিতে আমার নতুন সি ++ 11 'অটো' বৈশিষ্ট্যটি ব্যবহার করা উচিত?


20

autoবিশেষত লুপগুলির জন্য কীওয়ার্ডটি ব্যবহার করার পক্ষে কী কী সুবিধা রয়েছে ?

for(std::vector<T>::iterator it = x.begin(); it != x.end(); it++ )
{
   it->something();
}

for(std::map<T>::iterator it = x.begin(); it != x.end(); it++ )
{
   it->second->something();
}

for(auto it = x.begin(); it != x.end(); it++ )
{
   it->??
}

দেখে মনে হচ্ছে আপনি যদি মানচিত্রের জন্য একটি ইেটরেটর বা ভেক্টর ব্যবহার করেন firstবা না জানেন তবে আপনি জানেন না যে secondকেবলমাত্র অবজেক্টটির বৈশিষ্ট্য ব্যবহার করতে হবে বা না করতে হবে , না?

এটি কীওয়ার্ডটি ব্যবহার করতে হবে কিনা তা নিয়ে সি # বিতর্ক সম্পর্কে মনে করিয়ে দেয় var। আমি এখন পর্যন্ত যে ধারণাটি পেয়ে যাচ্ছি তা হ'ল সি ++ বিশ্বের লোকেরা সি # বিশ্বের autoচেয়ে কম লড়াইয়ের সাথে কীওয়ার্ডটি গ্রহণ করতে প্রস্তুত var। আমার জন্য আমার প্রথম প্রবৃত্তিটি হল আমি ভেরিয়েবলের ধরণটি জানতে পছন্দ করি যাতে আমি এটিতে কী অপারেশনগুলি আশা করতে পারি তা জানতে পারি।


3
অপেক্ষা কর ব্যবহার হবে কিনা তা নিয়ে লড়াই চলছে var? আমি সেটা মিস করছিলাম.
পিডিআর

21
আরও ভাল, আপনি কেবল for (auto& it : x)(অথবা আপনি অনুলিপি করতে চান তবে রেফারেন্স ছাড়াই) ব্যবহার করতে পারেন
ট্যামস সেজেলি

7
আমার কাছে মনে হচ্ছে আপনি যদি লিখিত বিষয়বস্তুগুলি নিয়ে পুনরাবৃত্তি করতে একটি লুপ লিখছেন xএবং আপনি কী জানেন তাও জানেন না x, আপনি সেই লুপটি প্রথম স্থানে লিখবেন না ;-)
নিকি

@ ফিশ: লুপগুলি নিয়মের জন্য ভিত্তিক পরিসর, তবে আমি প্যাডেন্টিক এবং কাজটি করতাম: পরিবর্তে লুপের উপর ভিত্তি করে ব্যাপ্তি ব্যবহার করার সময় 'টি (এটি এবং এটি: এক্স)', কারণ আমি মনে করি অটো ব্যবহারের চেয়ে কম তথ্যবহুল রয়েছে। আমার মনে অটো ব্যবহারের ধরণ।
মার্টিয়ারেট

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

উত্তর:


38

সি ++ এর অনুপ্রেরণাগুলি আরও চরম, কারণ রূপগুলি এবং অন্যান্য জিনিসের কারণে প্রকারগুলি সি # প্রকারের চেয়ে আরও বেশি জটিল এবং জটিল হয়ে উঠতে পারে। autoস্পষ্টত প্রকারের চেয়ে লেখার জন্য এবং পড়ার পক্ষে দ্রুত এবং আরও নমনীয় / রক্ষণাবেক্ষণযোগ্য মানে, আপনি কি টাইপ শুরু করতে চান?

boost::multi_map<NodeType, indexed_by<ordered_unique<identity<NodeType>>, hashed_non_unique<identity<NodeType>, custom_hasher>>::iterator_type<0> it

এটি পুরো টাইপও নয়। আমি কয়েকটি টেম্পলেট আর্গুমেন্ট মিস করেছি।


8
উদাহরণস্বরূপ +1, তবে এটি "আধুনিক" সি ++ এর অবস্থা সম্পর্কেও কিছু জানায়।
zvrba

22
@ জেভিআরবা: হ্যাঁ- জেনেরিক সুবিধাগুলি সি # এর চেয়ে অনেক বেশি শক্তিশালী।
ডেড এমজি

4
যে কি হয় typedef জন্য
gbjbaanb

19
@gbjbaanb না, এটাই তার autoজন্য। নকশা করে. typedefসাহায্য করে, তবে autoআরও সাহায্য করে।
কনরাড রুডল্ফ

1
টাইপডিফ এই যুক্তিটিকে অকার্যকর করে দেয় যে "স্বতঃআপনার ব্যবহার দীর্ঘতর ধরণের জন্য নয়"
মাইকেল

28

আপনার উদাহরণে:

for(auto it = x.begin(); it != x.end(); i++)
{
  it->??
}

xদৃশ্যমান জন্য এখানে একটি ঘোষণা থাকতে হবে । অতএব প্রকারটি itসুস্পষ্ট হওয়া উচিত। যদি প্রকারটি xসুস্পষ্ট না হয় তবে পদ্ধতিটি খুব দীর্ঘ, বা শ্রেণিটি খুব বড়।


7
এছাড়াও, xএকটি ধারকটির জন্য খুব খারাপ পরিবর্তনশীল নাম। কিছু পরিস্থিতিতে আপনি সম্ভবত (অর্থ মূল্যবান) নামটি দেখতে এবং সম্ভাব্য ক্রিয়াকলাপগুলি অনুমান করতে পারেন।
সর্বোচ্চ

@ ম্যাক্স: কেবল xজেনেরিক উদাহরণ হিসাবে ব্যবহৃত , আমি বেশ বর্ণনামূলক পরিবর্তনশীল নামগুলি ব্যবহার করার প্রবণতা রাখি।
ব্যবহারকারীর

@ ব্যবহারকারী অবশ্যই, আমি ধরে নিই নি যে এটি বাস্তব-জগতের উদাহরণ;)
সর্বাধিক

14

আপত্তি ! লোড প্রশ্ন।

আপনি আমাকে ব্যাখ্যা করতে পারেন কেন ??এটিতে তৃতীয় কোড রয়েছে , তবুও প্রথম এবং দ্বিতীয়টি নেই? ন্যায্যতার জন্য, আপনার কোডটি অবশ্যই নীচে পড়তে হবে :

for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)
{
   it->???
}

for(std::map<T>::iterator it = x.begin(); it != x.end(); i++)
{
   it->second->???
}

সেখানে। আপনি ব্যবহার না করলেও একই সমস্যা auto

এবং সমস্ত ক্ষেত্রে, উত্তর একই: প্রসঙ্গ বিষয়গুলি । আপনি বিচ্ছিন্নভাবে কোডের কোনও অংশ সম্পর্কে অর্থপূর্ণভাবে কথা বলতে পারবেন না। এমনকি যদি আপনি টেম্পলেটগুলি না ব্যবহার করেন তবে কিছু কংক্রিট টাইপ ব্যবহার করেন তবে এটি কেবল অন্য কোথাও সমস্যাটি স্থানান্তরিত করতে পারে, যেহেতু আপনার কোড পাঠককে সেই ধরণের ঘোষণার বিষয়ে জানতে হবে।

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

সম্পর্কিত var(যেহেতু আপনি স্পষ্টভাবে এটি উল্লেখ করেছেন), ব্যবহারের জন্য সি # সম্প্রদায়ে একটি বিস্তৃত sensকমত্যও রয়েছে । এর ব্যবহারের বিরুদ্ধে তর্কগুলি সাধারণত ভ্রান্তিতে নির্মিত হয়var


1
আমি মনে করি বিন্দুটি ছিল, অটো দিয়ে আপনি কী জানেন না আপনি কী রেখেছিলেন ... এটি কি আপনার কোড নির্দিষ্ট "কিছু" বা এটি কোনও ডেটা টাইপের সাথে সম্পর্কিত যা আপনার ডেটা অবজেক্টে আনপ্যাকিংয়ের পদ্ধতিতে "কিছু" রয়েছে
মাইকেল শ

1
@Ptolemy এবং আমার বক্তব্য হচ্ছে: অন্য দুটি কোডের মাধ্যমে আপনি এছাড়াও (সাধারণত) পরবর্তী কি করা জানি না: Tযেমন ব্যবহারকারীকে অস্বচ্ছ হয় auto। তবুও একটা ঠিক আছে বলে মনে করা হচ্ছে অন্যটি নয় ?! এটা বোঝা যায় না। ওপির ক্ষেত্রে, Tএকটি স্বেচ্ছাসেবী প্রকারের জন্য একটি স্ট্যান্ড-ইন। বাস্তব কোডে এটি টেমপ্লেট (for typename std::vector<T>::iterator…)বা ক্লাস ইন্টারফেসের ব্যবহার হতে পারে । উভয় ক্ষেত্রেই, প্রকৃত প্রকারটি ব্যবহারকারী থেকে লুকানো থাকে এবং তবুও আমরা নিয়মিত সমস্যা ছাড়াই এই জাতীয় কোড লিখি।
কনরাড রুডল্ফ

1
আসলে, হ্যাঁ আপনি করেন। যদি এটি ভেক্টর হয় তবে আপনি জানেন যে আপনাকে করা দরকার -> এবং তারপরে আপনার ডেটা ধরণের অ্যাক্সেস রয়েছে। যদি এটির মানচিত্র থাকে তবে আপনি জানেন যে আপনাকে করতে হবে -> দ্বিতীয়-> এবং তারপরে আপনার ডেটা টাইপের অ্যাক্সেস রয়েছে যদি এটির অটো হয় তবে আপনার ডেটা টাইপের অ্যাক্সেস পেতে আপনার কী করতে হবে তা আপনি জানেন না। আপনি "এসটিএল সংগ্রহের মধ্যে থাকা ডেটা টাইপ কী" এর সাথে "আমাদের মধ্যে কোন এসটিএল সংগ্রহের ধরণ রয়েছে" তা বিভ্রান্ত বলে মনে হচ্ছে। অটো এই সমস্যাটিকে আরও খারাপ করে তোলে।
মাইকেল শ 11

1
@ টলেমি ব্যবহার করার সময় এই সমস্ত যুক্তি ঠিক ততটাই সত্য autoxপ্রেক্ষাপট থেকে অপারেশনগুলি কী সমর্থন করে তা দেখতে এটি তুচ্ছ । প্রকৃতপক্ষে, প্রকারটি আপনাকে কোনও অতিরিক্ত তথ্য দেয় না : উভয় ক্ষেত্রে আপনাকে সমর্থিত ক্রিয়াকলাপগুলির সেট বলার জন্য কিছু গৌণ (আইডিই, ডকুমেন্টেশন, জ্ঞান / মেমরি) প্রয়োজন।
কনরাড রুডল্ফ

1
@ টলেমি এটি কেবল সত্য যদি আপনি অত্যন্ত সঙ্কুচিত অবস্থায় থাকেন যে আপনি কী জানেন কী জানেন না beginতবে আপনি কী তা std::vector<>::iteratorজানেন। এবং আপনাকে একটি খারাপ প্রোগ্রামিং সরঞ্জাম ব্যবহার করতে হবে যা আপনাকে এই তথ্যকে তুচ্ছভাবে দিতে পারে না। এটি অত্যন্ত সংশ্লেষিত। প্রকৃতপক্ষে, আপনি হয় উভয় জানি beginএবং iteratorবা তন্ন তন্ন, এবং আপনি একটি IDE বা সম্পাদক নির্দ্ধিধায় প্রাসঙ্গিক তথ্য আপনার জন্য উপলব্ধ করতে পারেন ব্যবহার করা উচিত। প্রতিটি আধুনিক আইডিই এবং প্রোগ্রামিং সম্পাদক এটি করতে পারেন।
কনরাড রুডল্ফ

11

প্রো

তোমার গোপন সংকেত :

for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)

টেমপ্লেট নির্ভর নামের কারণে সংকলন করতে যাচ্ছে না।

এটি সঠিক বাক্য গঠন:

for( typename std::vector<T>::iterator it = x.begin(); it != x.end(); i++)

এখন দেখুন টাইপ ডিক্লেয়ারেশনটি কত দীর্ঘ। autoকীওয়ার্ডটি চালু করার কারণ এটি জানায় । এই :

for( auto it = x.begin(); it != x.end(); i++)

আরও সংক্ষিপ্ত। সুতরাং, এটি একটি প্রো।


, CON

আপনাকে কিছুটা সতর্ক হতে হবে। কীওয়ার্ডের সাহায্যে autoআপনি যে ধরণের ঘোষনা করেছেন তা পাবেন।

উদাহরণ স্বরূপ :

std::vector< int > v{ 1, 2, 3, 4 };
for ( auto it : v )
{
  ++ it;   // ops modifying copies of vector's elements
}

বনাম

std::vector< int > v{ 1, 2, 3, 4 };
for ( auto & it : v )   // mind the reference
{
  ++ it;   // ok, vector's elements modified
}

উপসংহারে: হ্যাঁ, আপনার এটি করা উচিত, তবে এটি অতিরিক্ত ব্যবহার করা উচিত নয়। কিছু লোক এটিকে অত্যধিক ব্যবহার করতে ঝোঁক করে এবং সর্বত্র অটোতে রাখে, যেমন পরবর্তী উদাহরণের মতো:

auto i = 0;

বনাম

int i = 0;

auto i = 0। নির্দোষ প্রমাণিত হন। আমি তা করি. তবে এটি কারণ কারণ আমি জানি এটি 0একটি আক্ষরিক int। (এবং একটি অক্টাল ধ্রুবক ;-))
লরেন্ট এলএ রিজজা

6

হ্যাঁ তোমার উচিৎ! autoপ্রকারটি মুছে না; আপনি কী জানেন তা না x.begin()জানলেও, সংকলকটি জানেন এবং যদি আপনি টাইপটি ভুলভাবে ব্যবহার করার চেষ্টা করেন তবে একটি ত্রুটি প্রতিবেদন করবে। এছাড়াও, mapএকটি দিয়ে অনুকরণ করা অস্বাভাবিক নয় vector<pair<Key,Value>>, সুতরাং কোডটি autoউভয় অভিধান উপস্থাপনের জন্য কাজ করবে।


4

হ্যাঁ, আপনার autoএকটি ডিফল্ট নিয়ম হিসাবে ব্যবহার করা উচিত । স্পষ্টভাবে প্রকারটি নির্দিষ্ট করে দেওয়ার তুলনায় এর কাঁচা সুবিধা রয়েছে:

  • এটি আপনাকে সংকলকটি ইতিমধ্যে সচেতন জিনিসগুলি টাইপ করে না।
  • এটি ভেরিয়েবলের ধরণটিকে "বরাবর" ফিরতি মূল্যের ধরণের যে কোনও পরিবর্তন করতে দেয়।
  • এটি করা, এটি নিখুঁত রূপান্তরগুলির নীরব ভূমিকা এবং স্থানীয় পরিবর্তনশীল সূচনাতে টুকরা আটকা দেয় ।
  • এটি টেমপ্লেটগুলিতে কিছু স্পষ্ট ধরণের গণনার প্রয়োজনকে সরিয়ে দেয়।
  • এটি দীর্ঘ নামের সাথে রিটার্নের প্রকারের নামকরণের প্রয়োজনীয়তা সরিয়ে দেয়। (আপনি যা সংকলক ডায়াগনস্টিকস থেকে অনুলিপি করেছেন)

আপনার পছন্দ এখানেই। আপনার পছন্দ নেই এমন ক্ষেত্রেও রয়েছে:

  • এটি ল্যাম্বদার ধরণের মতো অপরিবর্তনীয় ধরণের ভেরিয়েবলগুলি ঘোষণার অনুমতি দেয়।

আপনি যদি ঠিক জানেন তবে autoএটির কোনও অসুবিধা নেই ided

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.