সি ++ এ অটো দিয়ে ভেরিয়েবলগুলি ঘোষণার কোনও খারাপ দিক রয়েছে কি?


143

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

autoভেরিয়েবলগুলি সুস্পষ্টভাবে ঘোষণার পরিবর্তে ডিক্লেয়ার করার ক্ষেত্রে কি কোনও ত্রুটি রয়েছে ?


1
আরও দেখুন: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 34৪৪9৯71 //২ , স্ট্যাকওভারফ্লো / সেকশনস / ১৫৫৪৪6161/২ , স্ট্যাকওভারফ্লো / সিকিউশনস / 00০০০০459/… , স্ট্যাকওভারফ্লো / সিকিউশনস / 8430053 / is- c11- auto-type- dan خطرناک , এবং সম্ভবত অন্যদের। এগুলি নির্ভুল নকল কিনা তা নিশ্চিত নন তবে তারা অবশ্যই প্রার্থী।
কোডি গ্রে

3
আমি কেবলমাত্র খারাপ দিকটিই পেয়েছিলাম যখন আমাকে এমন একটি (কনসোল) প্ল্যাটফর্মের কোড বেস পোর্ট করতে হয়েছিল যার সংকলকটি সমর্থন করে না (এবং সমর্থন করার কোনও ইচ্ছা ছিল না) সি ++ 11 বৈশিষ্ট্য!
স্যাম

7
কেবল সম্পূর্ণতার জন্য GotW # 94 "প্রায় সর্বদা অটো": herbsutter.com/2013/08/12/…
রিচার্ড ক্রিটেন

1
আমি সিপিসকাস্ট শুনছিলাম এবং সংঘর্ষে বি / ডাব্লু অটো এবং তালিকার সূচনাগুলির উল্লেখ ছিল। আমি সেই পডকাস্টটি সন্ধান করার চেষ্টা করব।
অভিনব গৌনিয়াল

2
আমি মনে করি প্রথম খারাপ
দিকটি

উত্তর:


111

আপনি কেবল ত্রুটিগুলি সম্পর্কে জিজ্ঞাসা করেছেন, তাই আমি সেগুলির কয়েকটি হাইলাইট করছি। ভাল ব্যবহার করা হয়, পাশাপাশি autoবিভিন্ন সুবিধা আছে। ত্রুটিগুলি অপব্যবহারের স্বাচ্ছন্দ্যের ফলে এবং অযৌক্তিক উপায়ে আচরণ করার কোডের সম্ভাবনা বৃদ্ধি করার ফলে ঘটে।

মূল অসুবিধাটি হ'ল, ব্যবহার করে autoআপনি প্রয়োজনীয়ভাবে অবজেক্টটি কীভাবে তৈরি হচ্ছে তা জানেন না। এমন কিছু অনুষ্ঠানও রয়েছে যেখানে প্রোগ্রামার এক ধরণের সংকলককে কমপ্লেক্সের প্রত্যাশা করতে পারে তবে সংকলকটি দৃ .়তার সাথে অন্যটিকে হ্রাস করে।

মত একটি ঘোষণা দেওয়া

auto result = CallSomeFunction(x,y,z);

কী ধরণের তা আপনার অগত্যা জ্ঞান নেই result। এটি একটি হতে পারে int। এটি একটি পয়েন্টার হতে পারে। এটা অন্য কিছু হতে পারে। যারা সকলেই বিভিন্ন অপারেশন সমর্থন করে। আপনি নাটকীয়ভাবে একটি সামান্য পরিবর্তন মত কোড পরিবর্তন করতে পারেন

auto result = CallSomeFunction(a,y,z);

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

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

অন্য, আরও সাধারণ ঘাটতি হ'ল autoকোডটি কী করছে সে সম্পর্কে চিন্তাভাবনা না করে এবং এটি সঠিক করার জন্য কাজ করার চেয়ে প্রোগ্রামারকে কোডটি সংকলন করতে বাধ্য করার জন্য একটি ভোঁতা যন্ত্র হিসাবে ব্যবহার করার প্রলোভন ।


58
এটি লক্ষণীয় আকর্ষণীয় যে এই ধরণের উদাহরণগুলি যদি ব্যবহারের অসুবিধা হয় autoতবে বেশিরভাগ হাঁস-টাইপের ভাষা নকশার দ্বারা এ জাতীয় অপূর্ণতা ভোগ করে!
লেবেন আসা

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

16
@ ডেভসোলার: T CallSomeFunction(T, int, int)ডিজাইনের ত্রুটি কেন হবে ? স্পষ্টতই এটি "তার যুক্তিগুলির ক্রমের উপর নির্ভর করে একটি ভিন্ন ধরণের প্রত্যাবর্তন করে।"
এমসাল্টারস 13:58

9
"প্রধান অসুবিধাটি হ'ল, ব্যবহার করে autoআপনি প্রয়োজনীয় অবজেক্টটি কীভাবে তৈরি হচ্ছে তা জানেন না।" আপনি কেন এটিকে সমস্যা auto, এবং সুব্যাক্স্প্রেশন টেম্পোরারিগুলির কোনও সমস্যা নয় তা বিশদ দিয়ে বলতে পারেন ? কেন auto result = foo();খারাপ, কিন্তু foo().bar()না?
অ্যাঞ্জিউ আর তাই

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

76

এটি autoহুবহু মূলত কোনও ত্রুটি নয় , তবে ব্যবহারিক দিক থেকে এটি কারও কারও কাছে একটি সমস্যা বলে মনে হচ্ছে। মূলত, কিছু লোক হয়: ক) autoপ্রকারের জন্য ত্রাণকারীর হিসাবে বিবেচনা করে এবং এটি ব্যবহার করার সময় তাদের মস্তিষ্ক বন্ধ করে দেয়, বা খ) ভুলে যান যে autoসর্বদা মূল্য প্রকারের জন্য ব্যয় করে। এর ফলে লোকেরা এই জাতীয় জিনিসগুলি করতে পারে:

auto x = my_obj.method_that_returns_reference();

ওহো, আমরা গভীরভাবে কিছু বস্তু অনুলিপি করেছি। এটি প্রায়শই বাগ বা কার্য সম্পাদন ব্যর্থ হয়। তারপরে, আপনি অন্য উপায়েও দুলতে পারেন:

const auto& stuff = *func_that_returns_unique_ptr();

এখন আপনি একটি ঝুঁকির রেফারেন্স পাবেন। এই সমস্যাগুলি মোটেই সৃষ্টি হয় না auto, তাই আমি তাদের বিরুদ্ধে বৈধ যুক্তিগুলি বিবেচনা করি না। তবে মনে হয় না autoযে আমি শুরুতে তালিকাভুক্ত কারণগুলির জন্য এই বিষয়টিকে (আমার ব্যক্তিগত অভিজ্ঞতা থেকে) আরও সাধারণ করে তোলে।

আমি মনে করি যে সময় দেওয়া লোকেরা সামঞ্জস্য করবে এবং শ্রমের বিভাজনটি বুঝতে পারবে: autoঅন্তর্নিহিত ধরণকে হ্রাস করে তবে আপনি এখনও রেফারেন্স-নেস এবং কনস্ট-নেস সম্পর্কে চিন্তা করতে চান। তবে এটি কিছুটা সময় নিচ্ছে।


আপনি কেন কোনও ব্যয়বহুল অবজেক্টটি গভীরভাবে অনুলিপি করতে পারবেন?
লরেন্ট এলএ রিজ্জা

3
@ লরেন্টলারিজা: কিছু ক্লাসে অনুলিপি নির্মাণকারী থাকে কারণ তাদের মাঝে মাঝে প্রয়োজন হয় (যেমন উদাহরণস্বরূপ std::vector)। অনুলিপি করা ব্যয়বহুল হওয়া কোনও শ্রেণীর সম্পত্তি নয়, তবে পৃথক বস্তুর সম্পত্তি। সুতরাং method_that_returns_referenceএমন কোনও শ্রেণীর কোনও অবজেক্টের উল্লেখ করতে পারে যার অনুলিপি নির্মাণকারী রয়েছে, তবে কোন বিষয়টি অনুলিপি করা (এবং এটি থেকে সরানো যায় না) বেশ ব্যয়বহুল বলে মনে হয়।
মার্ক ভ্যান লিউউইন

@ মার্কওয়ানলিউউইন: যদি বিষয়টির অনুলিপি ব্যয়বহুল হয় এবং সেখান থেকে সরানো যায় না তবে এটি কেন সংরক্ষণ করা হবে std::vector? (কারণ এটি হতে পারে, হ্যাঁ, বা আপনি ক্লাসটি নিয়ন্ত্রণ করেন না, তবে এটি বিন্দু নয়) যদি কপি করা ব্যয়বহুল হয়, (এবং কোনও সংস্থার মালিকানা নেই, কারণ এটি অনুলিপিযোগ্য) তবে কেন বস্তুটিতে COW ব্যবহার করবেন না? ডেটা লোকালটি ইতিমধ্যে বস্তুর আকারের দ্বারা নিহত হয়েছে।
লরেন্ট এলএ রিজ্জা

2
@ লরেন্টলারিজ্জা ভেক্টরে সঞ্চিত কোনও কিছুর ব্যয়বহুল উদাহরণ নয়, কেবল নিয়মিত যেমন ভেক্টর <ডাবল> কপি করা ব্যয়বহুল, এটি হিপ বরাদ্দ + ও (এন) এর কাজ। চলাচল একটি লাল রঙের হেরিং। আমি প্রদর্শিত প্রথম লাইনটি অনুলিপি করবে, সরানো হবে না, যদি না ফেরত রেফারেন্সটি মূল্যের উল্লেখ হয়। COW সত্যিই এখানে বা সেখানে নেই। আসল বিষয়টি হ'ল অনুলিপি করা জিনিসগুলি সর্বদা উপস্থিত থাকবে।
নীড় ফ্রিডম্যান

4
@ ইয়াক্ক এটি নিরাপদে এটি করতে পারে না, কারণ এটি টুকরো টুকরো হয়ে যেতে পারে। এটি কেবলমাত্র নিরাপদ কাজটিই করতে পারে তা হ'ল = deleteওভারলোড। যদিও আরও সাধারণভাবে আপনি বলেন এটি একটি সমাধান। এটি আপনার আগ্রহী হলে এটি আমি অনুসন্ধান করেছি । Nirfriedman.com/2016/01/18/…
নীড় ফ্রিডম্যান

51

অন্যান্য উত্তরগুলি অসুবিধাগুলির উল্লেখ করে যেমন "ভেরিয়েবলের ধরণ কী তা আপনি সত্যিই জানেন না।" আমি বলব যে এটি মূলত কোডের opালু নামকরণের কনভেনশনের সাথে সম্পর্কিত। যদি আপনার ইন্টারফেসগুলি স্পষ্টরূপে নামকরণ করা হয় তবে সঠিক ধরণটি কী তা আপনার যত্নের দরকার নেই। অবশ্যই, auto result = callSomeFunction(a, b);আপনাকে বেশি কিছু বলে না। তবে এর সঠিক প্রকারটি কী তা চিন্তা না করেই auto valid = isValid(xmlFile, schema);আপনাকে যথেষ্ট পরিমাণে ব্যবহার করার জন্য আপনাকে বলে valid। সর্বোপরি, ন্যায়সঙ্গতভাবে if (callSomeFunction(a, b)), আপনি টাইপটিও জানতেন না। অন্য কোনও subexpression অস্থায়ী বস্তুর সাথে একই। সুতরাং আমি এটিকে সত্যিকারের অপূর্ণতা মনে করি না auto

আমি বলব এর প্রাথমিক অসুবিধাটি হ'ল কখনও কখনও, সঠিক রিটার্ন টাইপটি আপনি কাজ করতে চান তা নয়ফলস্বরূপ, কখনও কখনও বাস্তব রিটার্ন টাইপ বাস্তবায়ন / অপ্টিমাইজেশনের বিশদ হিসাবে "যৌক্তিক" রিটার্ন টাইপের থেকে আলাদা হয়। এক্সপ্রেশন টেম্পলেট একটি প্রধান উদাহরণ। ধরা যাক আমাদের এটি আছে:

SomeType operator* (const Matrix &lhs, const Vector &rhs);

কথাটি, আমরা আশা SomeTypeহতে Vector, এবং আমরা স্পষ্টভাবে আমাদের কোডে যেমন এটা বিবেচনা করতে চাই। তবে এটি সম্ভব যে অপ্টিমাইজেশনের উদ্দেশ্যে, বীজগণিত গ্রন্থাগার আমরা প্রয়োগকারী এক্সপ্রেশন টেম্পলেট ব্যবহার করি এবং আসল প্রত্যাবর্তনের ধরণটি হ'ল:

MultExpression<Matrix, Vector> operator* (const Matrix &lhs, const Vector &rhs);

এখন, সমস্যাটি হ'ল MultExpression<Matrix, Vector>সমস্ত সম্ভাবনা একটি const Matrix&এবং const Vector&অভ্যন্তরীণভাবে সঞ্চয় করবে ; এটি প্রত্যাশা করে যে এটি Vectorতার পূর্ণ-প্রকাশের সমাপ্তির আগে একটিতে রূপান্তরিত হবে । আমাদের যদি এই কোডটি থাকে তবে সব ঠিক আছে:

extern Matrix a, b, c;
extern Vector v;

void compute()
{
  Vector res = a * (b * (c * v));
  // do something with res
}

তবে, আমরা যদি autoএখানে ব্যবহার করতাম তবে আমরা সমস্যায় পড়তে পারি:

void compute()
{
  auto res = a * (b * (c * v));
  // Oops! Now `res` is referring to temporaries (such as (c * v)) which no longer exist
}

3
@ নিরিফ্রিডম্যান আপনি ঠিক বলেছেন এটি শক্তিশালী, তবে আমি আসলে অনুভব করি যে autoএর খুব কম ঘাটতি রয়েছে, তাই আমি সেই শক্তির পাশে দাঁড়িয়েছি। এবং প্রক্সি ইত্যাদির অন্যান্য উদাহরণগুলির মধ্যে বিভিন্ন "স্ট্রিং বিল্ডার" এবং ডিএসএল-তে পাওয়া একই ধরণের জিনিস অন্তর্ভুক্ত রয়েছে।
অ্যাঞ্জু আর তাই

2
আমি এক্সপ্রেশন টেম্পলেট এবং এর autoআগেও কামড়েছি , বিশেষত ইগেন লাইব্রেরির সাথে। এটি বিশেষত জটিল কারণ সমস্যাটি প্রায়শই ডিবাগ বিল্ডগুলিতে প্রদর্শিত হয় না।
ড্যান

1
ব্যবহারের autoযখন ব্যবহার এছাড়াও দান্ত দিয়া ফুটা করা করতে পারেন আরমাডিলো ম্যাট্রিক্স গ্রন্থাগার, যা অপ্টিমাইজেশান উদ্দেশ্যে টেমপ্লেট মেটা-প্রোগ্রামিং ভারী ব্যবহার করে। ভাগ্যক্রমে বিকাশকারীরা .eval () ফাংশন যোগ করেছেন যা সমস্যাগুলি এড়াতে ব্যবহার করা যেতে পারেauto
mtall

2
"যদি আপনার ইন্টারফেসগুলি স্পষ্টরূপে নামকরণ করা হয় তবে সঠিক ধরণটি কী তা আপনার যত্নের দরকার নেই" আপনার সংকলকটি ভেরিয়েবলের নাম অধ্যয়ন করে আপনার কোডের সঠিকতা পরীক্ষা করতে পারবেন না। এটি একটি টাইপ সিস্টেমের সম্পূর্ণ পয়েন্ট। অন্ধভাবে বাইপাস করে বোকা!
অরবিটে

1
@ অ্যাঞ্জিউ: অস্থায়ীদের জন্য এটি কোনও সমস্যা নয় কারণ আপনি সাধারণত তাৎক্ষণিকভাবে এগুলি ব্যবহার করেন, যা autoসাধারণত কোনও ধরণের চেক জড়িত না করে (এবং autoসর্বত্র ছড়িয়ে ছিটিয়ে থাকা এই ধরণের সুরক্ষা অন্যত্র যেমনভাবে নেয় তেমন)। এটি একটি ভাল তুলনা না।
অরবিটে

13

একটি অপূর্ণতা হ'ল কখনও কখনও আপনি এটি const_iteratorদিয়ে ঘোষণা করতে পারেন না autoএই প্রশ্ন থেকে নেওয়া কোডের এই উদাহরণে আপনি সাধারণ (নন কনস্ট্যান্ড) পুনরাবৃত্তি পাবেন :

map<string,int> usa;
//...init usa
auto city_it = usa.find("New York");

3
ঠিক আছে, যে iteratorকোনও ক্ষেত্রে আপনার মানচিত্র অ-ব্যবহারযোগ্য হওয়ায় আপনি এটি পেতে পারেন const। আপনি যদি এটিকে রূপান্তর করতে চান const_iterator, হয় স্বাভাবিক হিসাবে সুস্পষ্টভাবে ভেরিয়েবল টাইপ নির্দিষ্ট করুন, বা কোনও পদ্ধতি বের করুন যাতে আপনার মানচিত্রটি আপনার প্রসঙ্গে প্রযোজ্য find। (আমি পরেরটি পছন্দ করি। এসআরপি।)
লরেন্ট এলএ রিজ্জা

auto city_it = static_cast<const auto&>(map).find("New York")? অথবা, সি ++ 17, দিয়ে auto city_if = std::as_const(map).find("New York")
দেব নুল

11

এটি আপনার কোডটি পড়ার জন্য কিছুটা শক্ত বা ক্লান্তিকর করে তোলে। এরকম কিছু কল্পনা করুন:

auto output = doSomethingWithData(variables);

এখন, আউটপুট ধরণের জানতে, আপনাকে doSomethingWithDataফাংশনের স্বাক্ষরটি ট্র্যাক করতে হবে।


40
সর্বদা না। উদাহরণস্বরূপ auto it = vec.begin();তুলনায় পড়া অনেক সহজ std::vector<std::wstring>::iterator it = vec.begin();
জোনাথন পটার

4
একমত। এটি নির্ভর করে ব্যবহারের ক্ষেত্রে। আমি যে সম্পর্কে আরও সুনির্দিষ্ট হতে পারে।
স্কাম

1
@ সিয়ার্ড হ্যাঁ, যে লোকেরা এর মতো অটো ব্যবহার করে তারা ভুল করছে।
lciamp

6
"ফাংশন স্বাক্ষর সন্ধান করুন", যদি তা মাউস হোভার না হয় বা কোনও কী দূরে না থাকে ("প্রতীক অনুসরণ করুন" / "ঘোষণায় যান" / যাই হোক না কেন) আপনাকে আপনার সম্পাদককে আরও কনফিগার করতে হবে বা কোনও আইডিইতে স্যুইচ করুন যা কনফিগারেশন ছাড়াই এটি করতে পারে ... আপনার পয়েন্টটি এখনও কার্যকর is
হাইডে

6
আমি লক্ষ্য করেছি যে কোনও আইডিইতে নয়, চেকিনগুলি পর্যালোচনা করার সময় বিভিন্ন ডিফের ছোট ছোট পীফোলে! অটো দিয়ে তারা সেই কারণে পড়তে আরও কঠিন।
জেডিগোগস

10

এই বিকাশকারীর মতো আমিও ঘৃণা করি auto। বা বরং, লোকেরা কীভাবে অপব্যবহার করে তা আমি ঘৃণা করি auto

আমি (দৃ strong়) মতামতের মধ্যে যা autoআপনাকে জেনেরিক কোড লিখতে সহায়তা করার জন্য, টাইপিং হ্রাস করার জন্য নয়
সি ++ হ'ল এমন একটি ভাষা যার লক্ষ্য আপনাকে শক্তিশালী কোড লিখতে দেয়, উন্নয়নের সময়কে হ্রাস না করে।
এই C- এর অনেক বৈশিষ্ট্য থেকে মোটামুটি সুস্পষ্ট ++ কিন্তু দুর্ভাগ্যবশত একটি নতুন বেশী মত কয়েক autoযে চিন্তা তারা টাইপিং অলস হচ্ছে শুরু করা উচিত মধ্যে টাইপিং ভুল পথে চালিত মানুষ কমানো।

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

সাধারণত, আপনি যদি ব্যবহার করেন তবে autoএটি এমন হওয়া উচিত কারণ আপনার কোডটি কোনও যুক্তিসঙ্গত প্রকারের জন্য কাজ করে , আপনি যে ধরণের কাজ করতে চান তা লিখতে কেবল খুব অলসতার কারণে নয় । যদি আপনি autoঅলসতায় সহায়তা করার জন্য একটি সরঞ্জাম হিসাবে ব্যবহার করেন, তবে যা ঘটে তা হ'ল শেষ পর্যন্ত আপনি আপনার প্রোগ্রামে সূক্ষ্ম বাগগুলি প্রবর্তন করা শুরু করেন , সাধারণত আপনি অন্তর্নিহিত রূপান্তরগুলির কারণে ঘটে যা আপনি ব্যবহার করার কারণে ঘটে নি auto

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

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


3
which was great because typedef allowed the designer of the library to help you figure out what the return type should be, so that their library works as expected. When you use auto, you take away that control from the class's designer and instead ask the compiler to figure out what the type should beআসলেই কোনও ভাল কারণ নয় আইএমও। উদাহরণস্বরূপ, ভিজ্যুয়াল স্টুডিও 2015-তে আপ-টু-ডেট আইডিজি আপনাকে ঘোরাফেরা করে ভেরিয়েবলের ধরণটি পরীক্ষা করতে দেয় auto। এটি * ঠিক * এর মতোই typedef
সোম্বেরো চিকেন

@ জামেডি: আপনি সেখানে বেশ কয়েকটি গুরুত্বপূর্ণ পয়েন্ট মিস করছেন: (1) আপনার আইডিই যুক্তিটি কেবল তখনই কাজ করে যদি প্রকারটি কংক্রিটের নয়, প্রেরণিত নয়। আইডিই সম্ভবত নির্ভরশীল প্রকারের ক্ষেত্রে সঠিক প্রকারটি আপনাকে বলতে পারে না typename std::iterator_traits<It>::value_type। (২) পুরো বিষয়টি হ'ল অনুমানকৃত ধরণের কোডটির আগের ডিজাইনার দ্বারা উদ্দিষ্ট সঠিক ধরণের মতো "হুবহু একরকম " হওয়া উচিত নয় ; ব্যবহার করে auto, আপনি সঠিক প্রকারটি নির্দিষ্ট করার জন্য ডিজাইনারের ক্ষমতা কেড়ে নিচ্ছেন।
ব্যবহারকারী541686

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

@ নিরিফ্রিডম্যান: "... vector<bool>বাজে" ... ক্ষমা? আপনি কীভাবে bitsetপ্রয়োগ করা হয় বলে মনে করেন ? বা আপনি কি বিট পাত্রে পুরোপুরি বাজে কথা বলে বিবেচনা করছেন ?!
user541686

1
@ নিরিফ্রিডম্যান: ভেক্টর সম্পর্কে <বিউল> সম্পর্কে কিছুই আমার কাছে খবর নয়। আমি আপনাকে যা বলার চেষ্টা করছি এবং আপনি সম্পূর্ণরূপে বুঝতে অস্বীকার করছেন তা হ'ল এই প্রশ্নের বিটসেটের উদ্দেশ্য হিসাবে ভেক্টর <বিউল> থেকে আলাদা নয় - উভয়ই প্রক্সি ব্যবহার করে, কারণ প্রক্সিগুলি দরকারী বলে মনে করা হয়েছিল , এবং প্রক্সিগুলি কার্যকর যে সত্য তা অস্বীকার করে জীবন যাপনের পরিবর্তে আপনাকে গ্রহণ করা দরকার। আপনি কি অনুগ্রহ করে দরকারী যে এটি সম্পর্কে বিতর্কে পরিণত করা বন্ধ করতে পারেন? এটি বিতর্কের বিষয় নয়, এবং এগুলি সম্পর্কে আপনার মতামতটি আপনার মতামত, কোনও ধরণের সত্য নয়।
user541686

6

autoপ্রতি সেটের কোনও ত্রুটি নেই এবং আমি এটিকে নতুন কোডে সর্বত্র ব্যবহার করার পক্ষে (হাতে-ভারিভাবে) পরামর্শ দিই। এটি আপনার কোডকে ধারাবাহিকভাবে টাইপ-চেক করতে এবং নিরবচ্ছিন্নভাবে চুপচাপ এড়াতে সহায়তা করে। (যদি Bথেকে উদ্ভূত হয় Aএবং কোনও ফাংশন Aহঠাৎ করে ফিরে আসে Bতবে autoতার রিটার্নের মান সংরক্ষণ করার প্রত্যাশার সাথে আচরণ করে)

যদিও, প্রাক-সি ++ 11 লিগ্যাসি কোড সুস্পষ্টভাবে টাইপযুক্ত ভেরিয়েবলগুলির ব্যবহার দ্বারা প্রেরিত অন্তর্নিহিত রূপান্তরগুলির উপর নির্ভর করতে পারে। কোড আচরণ পরিবর্তন করতে একটি স্পষ্টত-টাইপযুক্ত ভেরিয়েবল পরিবর্তন করাauto , যাতে আপনি আরও সতর্ক হন।


ডাউনভোটিং ন্যায্য, তবে আপনি কেন মন্তব্য করতে পারেন?
লরেন্ট এলএ রিজ্জা

আমি আপনাকে হ্রাস করি নি, তবে autoপ্রতি সেটের কমতি রয়েছে (বা কমপক্ষে - অনেকে মনে করেন এটি করেন)। এই প্যানেল আলোচনায় দ্বিতীয় প্রশ্নে দেওয়া সূত্র, আলেকজান্দ্রেস্কু এবং মায়ারদের সাথে বিবেচনা করুন: আপনার যদি থাকে auto x = foo(); if (x) { bar(); } else { baz(); }এবং foo()ফিরে আসে bool- যদি foo()এনাম ফেরত দেওয়ার পরিবর্তে (দুটি পরিবর্তে তিনটি বিকল্প) কী হয়? autoকোড কাজ চালিয়ে, কিন্তু অপ্রত্যাশিত ফলাফল উত্পাদন করা হবে।
einpoklum

@ আইনপোকলুম: এবং আনস্কোপড এনামের ক্ষেত্রে কিছু পরিবর্তনের boolপরিবর্তে কি ব্যবহার করা যায় auto? আমি ভুল হতে পারি (এখানে যাচাই করতে পারি না) তবে আমি মনে করি কেবলমাত্র পার্থক্য হ'ল boolএর শর্তটি মূল্যায়নের পরিবর্তে পরিবর্তনশীল ঘোষণার সময় রূপান্তর ঘটে if। যদি enumস্কোপ করা থাকে তবে boolস্পষ্ট নোটিশ ছাড়াই রূপান্তর ঘটবে না।
লরেন্ট এলএ রিজ্জা

4

মূলশব্দটি autoকেবল প্রত্যাবর্তনের মান থেকে প্রকারটি হ্রাস করে। সুতরাং এটি পাইথন বস্তুর সাথে সমান নয়, যেমন equivalent

# Python
a
a = 10       # OK
a = "10"     # OK
a = ClassA() # OK

// C++
auto a;      // Unable to deduce variable a
auto a = 10; // OK
a = "10";    // Value of const char* can't be assigned to int
a = ClassA{} // Value of ClassA can't be assigned to int
a = 10.0;    // OK, implicit casting warning

autoসংকলনের সময় যেহেতু ছাড় করা হয়, তাই রানটাইমের সময়ে এটির কোনও অসুবিধা হবে না।


1
হ্যাঁ, এটি মূলত type()পাইথন যা করে তা করে। এটি টাইপকে হ্রাস করে, এটি সেই ধরণের কোনও নতুন ভেরিয়েবল তৈরি করে না।
lciamp

2
বাস্তবিক @lciamp, যে হবে decltypeautoবিশেষত ভেরিয়েবল অ্যাসাইনমেন্টের জন্য।
কিউবিক

4

এখন পর্যন্ত কেউ এখানে কী উল্লেখ করেনি, তবে আপনি যদি আমাকে জিজ্ঞাসা করেন তবে নিজের পক্ষে একটি উত্তর মূল্যবান।

যেহেতু (এমনকি প্রত্যেকেরই সচেতন হওয়া উচিত C != C++) সি লিখিত কোডটি সহজেই সি ++ কোডের জন্য একটি বেস সরবরাহ করার জন্য ডিজাইন করা যেতে পারে এবং তাই সি ++ সামঞ্জস্যপূর্ণ হওয়ার জন্য খুব বেশি প্রচেষ্টা ছাড়াই ডিজাইন করা যায়, এটি ডিজাইনের জন্য প্রয়োজনীয়তা হতে পারে।

আমি এমন কিছু বিধি সম্পর্কে জানি যেখানে থেকে কিছু ভাল সংজ্ঞায়িত কনস্ট্রাকশনগুলি Cএর জন্য C++বিপরীত invalid তবে এটি সহজেই ভাঙ্গা এক্সিকিউটেবলের ফলস্বরূপ এবং জ্ঞাত ইউবি-ক্লজটি প্রযোজ্য যা বেশিরভাগ সময় ক্র্যাশ বা যা কিছু (বা এমনকি অপরিবর্তিত থাকতে পারে, তবে এটি এখানে গুরুত্বপূর্ণ নয়) ফলে অদ্ভুত লুপিং দ্বারা লক্ষ্য করা যায়।

কিন্তু autoপ্রথমবার 1 এই পরিবর্তন!

autoকোডটি স্থানান্তরিত করার আগে আপনি স্টোরেজ-শ্রেণীর নির্দিষ্টকরণকারক হিসাবে ব্যবহার করেছেন তা কল্পনা করুন । এটি প্রয়োজনীয়ভাবেও হবে না (এটি যেভাবে ব্যবহৃত হয়েছিল তার উপর নির্ভর করে) "ব্রেক"; এটি আসলে নীরবে প্রোগ্রামটির আচরণ পরিবর্তন করতে পারে।

এটি কিছু মনে রাখা উচিত।


1 আমি প্রথমে সচেতন aware


1
সংকলনের চেষ্টা করার সময় আপনি যেভাবেই কোনও সংকলক ত্রুটি পেয়েছেন।
সোম্বেরো চিকেন

@ জামেডি: কী করবে? দ্বিধাবিভক্ত অর্থ সহ 2 টি বৈধ কোড পরিস্থিতি কেন ত্রুটিযুক্ত হতে হবে?
dhein

8
আপনি যদি intসি তে "কোনও প্রকারের ইঙ্গিত নেই" এর উপর নির্ভর করে থাকেন তবে আপনি এ থেকে যে সমস্ত খারাপ জিনিস পেয়ে যাবেন তা আপনি প্রাপ্য। এবং যদি আপনি এর উপর নির্ভর না করে থাকেন তবে কোনও ধরণের পাশাপাশিauto স্টোরেজ শ্রেণীর নির্দিষ্টকরণকারক হিসাবে ব্যবহার করা আপনাকে সি ++ এ একটি দুর্দান্ত সংকলন ত্রুটি দেয় (যা এই ক্ষেত্রে ভাল জিনিস)।
অ্যাঞ্জিউ আর এও

1
হ্যাঁ, আমি যে মামলার বিষয়টি উল্লেখ করছি তা এখনই ভালভাবে জেনে গেছে। আমি এটা করছি না। তবে এটি এমন একটি বিষয় যা অন্তত মাথায় রাখা উচিত।
'10

3

একটি কারণ যা আমি ভাবতে পারি তা হ'ল আপনি ফিরে আসা শ্রেণিকে বাধ্য করার সুযোগটি হারাবেন। যদি আপনার ফাংশন বা পদ্ধতিটি একটি দীর্ঘ bit৪ বিট ফিরে এসেছে এবং আপনি কেবল একটি 32 স্বাক্ষরবিহীন ইনট চেয়েছিলেন, তবে আপনি এটি নিয়ন্ত্রণ করার সুযোগটি হারাবেন।


1
স্ট্যাটিক_কাস্ট রয়েছে, এবং আইআইআরসি উদাহরণস্বরূপ মায়ার্সের কার্যকর আধুনিক সি ++ এমনকি এটি অটো-টাইপড ভেরিয়েবলের জন্য প্রকার নির্দিষ্ট করার জন্য ব্যবহার করার পরামর্শ দেয়।
হাইডে

2

আমি এই উত্তরে বর্ণিত হিসাবে autoকখনও কখনও আপনার উদ্দেশ্য নয় এমন মজার পরিস্থিতি তৈরি হতে পারে। আপনাকে স্পষ্ট করে বলতে auto&হবে রেফারেন্স টাইপ autoকরতে গিয়ে কেবল পয়েন্টার টাইপ তৈরি করতে পারে। প্রকৃত উল্লেখের পরিবর্তে রেফারেন্সের অনুলিপিটির ফলে, একসাথে স্পেসিফায়ারকে বাদ দিয়ে বিভ্রান্তির সৃষ্টি হতে পারে।


2
ওটা মজাদার নয় এটাই যা autoকরে, কখনই কোনও রেফারেন্স বা constটাইপ করে না। একটি autoরেফারেন্সের জন্য, আপনি আরও ভাল ব্যবহার করতে চাই auto&&। (সর্বজনীন রেফারেন্স) টাইপটি যদি অনুলিপি করার পক্ষে সস্তা না হয় বা কোনও সংস্থার মালিকানা থাকে, তবে প্রকারটি শুরু হওয়ার সাথে অনুলিপিযোগ্য হওয়া উচিত নয়।
লরেন্ট এলএ রিজ্জা

1

আরেকটি বিরক্তিকর উদাহরণ:

for (auto i = 0; i < s.size(); ++i)

একটি সতর্কতা উত্পন্ন করে ( comparison between signed and unsigned integer expressions [-Wsign-compare]), কারণ iএটি একটি স্বাক্ষরিত অন্তর্নিহিত। এটি এড়াতে আপনাকে যেমন লিখতে হবে যেমন

for (auto i = 0U; i < s.size(); ++i)

বা সম্ভবত আরও ভাল:

for (auto i = 0ULL; i < s.size(); ++i)

1
হ্যাঁ আমি এটিকে খুব বিরক্তিকর মনে করি। তবে ভাষার গর্তটি অন্য কোথাও। এই কোডটি সত্যিকারেরভাবে পোর্টেবল হওয়ার জন্য, sizeরিটার্ন ধরে ধরে size_t, আপনার কাছে size_tআক্ষরিক মতো থাকতে হবে 0z। তবে আপনি এটি করতে কোনও ইউডিএল ঘোষণা করতে পারেন। ( size_t operator""_z(...))
লরেন্ট এলএ রিজ্জা

1
খাঁটি তাত্ত্বিক আপত্তি: মূলধারার আর্কিটেকচারের unsignedসমস্ত মান ধরে রাখার মতো যথেষ্ট বড় std::size_tনা হওয়ার সম্ভাবনা খুব কম, তাই অসম্ভব ঘটনায় যে কারও কাছে একটি অযৌক্তিকভাবে বিশাল আকারের সংখ্যার উপাদানযুক্ত একটি ধারক ছিল, এটি ব্যবহার unsignedকরে নিম্ন রেঞ্জের উপর একটি অসীম লুপ তৈরি করতে পারে সূচকের। যদিও এটি কোনও সমস্যা হওয়ার সম্ভাবনা নেই, std::size_tপরিষ্কার কোড পেতে ব্যবহার করা উচিত যা সঠিকভাবে উদ্দেশ্যকে নির্দেশ করে। আমি নিশ্চিত না যে এমনকি unsigned long longপর্যাপ্ত পর্যাপ্তর জন্য গ্যারান্টিযুক্ত, যদিও বাস্তবে এটি সম্ভবত একই হতে হবে।
আন্ডারস্কোর_

@ মাউন্ডস_ডি: হ্যাঁ, ফেয়ার পয়েন্ট - unsigned long longকমপক্ষে 64৪ বিটের গ্যারান্টিযুক্ত, তবে তাত্ত্বিকভাবে এর size_tচেয়ে বড় হতে পারে, আমার ধারণা। অবশ্যই যদি আপনার ধারকটিতে> 2 ^ 64 উপাদান থাকে তবে আপনার সম্পর্কে চিন্তা করতে আরও বড় সমস্যা হতে পারে ... ;-)
পল আর

1

আমি মনে করি autoস্থানীয়করণ করা প্রসঙ্গে ব্যবহার করা ভাল, যেখানে পাঠক সহজেই এবং স্পষ্টতই তার প্রকারটি কেটে ফেলতে পারে, বা তার টাইপের মন্তব্য বা প্রকৃত টাইপকে অনুধাবনকারী একটি নাম সহ ভালভাবে নথিভুক্ত করতে পারে। এটি কীভাবে কাজ করে তারা বুঝতে পারে না যে তারা এটি ভুল উপায়ে গ্রহণ করতে পারে, পরিবর্তে templateবা অনুরূপ ব্যবহার করার মতো। আমার মতে এখানে ভাল এবং খারাপ ব্যবহারের কয়েকটি মামলা রয়েছে।

void test (const int & a)
{
    // b is not const
    // b is not a reference

    auto b = a;

    // b type is decided by the compiler based on value of a
    // a is int
}

ভাল ব্যবহার

Iterators

std::vector<boost::tuple<ClassWithLongName1,std::vector<ClassWithLongName2>,int> v();

..

std::vector<boost::tuple<ClassWithLongName1,std::vector<ClassWithLongName2>,int>::iterator it = v.begin();

// VS

auto vi = v.begin();

ফাংশন পয়েন্টার

int test (ClassWithLongName1 a, ClassWithLongName2 b, int c)
{
    ..
}

..

int (*fp)(ClassWithLongName1, ClassWithLongName2, int) = test;

// VS

auto *f = test;

খারাপ ব্যবহার

তথ্য প্রবাহ

auto input = "";

..

auto output = test(input);

ফাংশন স্বাক্ষর

auto test (auto a, auto b, auto c)
{
    ..
}

তুচ্ছ ঘটনা

for(auto i = 0; i < 100; i++)
{
    ..
}

আপনি যখন একটি চান int, আপনি যেতে হলে আপনাকে আরও একটি চর টাইপ করতে হবে auto। এটি অগ্রহণযোগ্য
10'6

@ রিরিটো হ্যাঁ, এটি intএখানে সহজেই দেখা যায় এবং টাইপিংও intকম হয়। এ কারণেই এটি একটি তুচ্ছ ঘটনা।
খালেদ.কে

0

আমি অবাক হয়েছি কেউ এর উল্লেখ করেন নি, তবে মনে করুন আপনি কোনও কিছুর বিবরণী গণনা করছেন:

#include <iostream>
using namespace std;

int main() {
    auto n = 40;
    auto factorial = 1;

    for(int i = 1; i <=n; ++i)
    {
        factorial *= i;
    }

    cout << "Factorial of " << n << " = " << factorial <<endl;   
    cout << "Size of factorial: " << sizeof(factorial) << endl; 
    return 0;
}

এই কোডটি এটিকে আউটপুট দেবে:

Factorial of 40 = 0
Size of factorial: 4

এটি অবশ্যই প্রত্যাশিত ফলাফল ছিল না। এটি ঘটেছিল কারণ autoভেরিয়েবল ফ্যাটোরিয়ালটির ধরণটি intনির্ধারণ করা হয়েছিল কারণ এটি নির্ধারিত হয়েছিল 1

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