আমি কখন সি ++ 14 স্বয়ংক্রিয় রিটার্নের ধরণের ছাড় ব্যবহার করব?


144

জিসিসি ৪.৮.০ প্রকাশিত হওয়ার সাথে সাথে আমাদের একটি সংকলক রয়েছে যা স্বয়ংক্রিয়ভাবে রিটার্ন টাইপ ছাড়ের সমর্থন করে, সি ++ ১৪ এর অংশ। সহ -std=c++1y, আমি এটি করতে পারি:

auto foo() { //deduced to be int
    return 5;
}

আমার প্রশ্ন: আমি কখন এই বৈশিষ্ট্যটি ব্যবহার করব? এটি কখন প্রয়োজনীয় এবং কখন কোড ক্লিনার করে?

দৃশ্যপট 1

আমি যে প্রথম দৃশ্যের কথা ভাবতে পারি তা যখনই সম্ভব হয়। এভাবে লেখা যায় এমন প্রতিটি ফাংশন হওয়া উচিত। এটির সাথে সমস্যাটি হ'ল এটি সর্বদা কোডটিকে আরও পঠনযোগ্য করে তুলবে না।

দৃশ্য 2

পরবর্তী পরিস্থিতিটি আরও জটিল রিটার্নের ধরন এড়ানো। খুব হালকা উদাহরণ হিসাবে:

template<typename T, typename U>
auto add(T t, U u) { //almost deduced as decltype(t + u): decltype(auto) would
    return t + u;
}

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

পরিস্থিতি 3

অপ্রয়োজনীয়তা রোধ করতে পরবর্তী:

auto foo() {
    std::vector<std::map<std::pair<int, double>, int>> ret;
    //fill ret in with stuff
    return ret;
}

সি ++ ১১-এ, আমরা কখনও কখনও কেবল return {5, 6, 7};কোনও ভেক্টরের জায়গায় রাখতে পারি, তবে এটি সর্বদা কার্যকর হয় না এবং আমাদের ফাংশন শিরোনাম এবং ফাংশন বডি উভয় প্রকারের নির্দিষ্ট করতে হবে। এটি নিখুঁতভাবে অপ্রয়োজনীয় এবং স্বয়ংক্রিয় রিটার্নের ধরণের ছাড় আমাদের সেই অপ্রয়োজনীয়তা থেকে বাঁচায়।

দৃশ্য 4

অবশেষে, এটি খুব সাধারণ ফাংশনের জায়গায় ব্যবহার করা যেতে পারে:

auto position() {
    return pos_;
}

auto area() {
    return length_ * width_;
}

কখনও কখনও, যদিও আমরা সঠিক প্রকারটি জানতে চেয়ে আমরা ফাংশনটি দেখতে পারি এবং এটি যদি এখানে সরবরাহ না করা হয় তবে আমাদের কোডের অন্য একটি বিন্দুতে যেতে হবে, যেখানে pos_কোথায় ঘোষিত হয়েছে।

উপসংহার

এই পরিস্থিতিগুলি নির্দিষ্ট করে দিয়ে, তাদের মধ্যে কোনটি এমন পরিস্থিতি হিসাবে প্রমাণিত হয় যেখানে কোডটি ক্লিনার তৈরিতে এই বৈশিষ্ট্যটি কার্যকর? আমি এখানে উল্লেখ করতে অবহেলা করা পরিস্থিতি সম্পর্কে কী? এই বৈশিষ্ট্যটি ব্যবহার করার আগে আমার কী সাবধানতা অবলম্বন করা উচিত যাতে এটি আমাকে পরে কামড়ায় না? এই বৈশিষ্ট্যটি টেবিলটিতে এমন নতুন কিছু এনেছে যা এটি ছাড়া সম্ভব নয়?

নোট করুন যে একাধিক প্রশ্ন বোঝার জন্য দৃষ্টিকোণগুলি অনুসন্ধান করার জন্য এটি থেকে কোন উত্তর দেওয়া উচিত।


18
আশ্চর্য প্রশ্ন! আপনি যখন জিজ্ঞাসা করছেন যে কোন পরিস্থিতি কোডটিকে "আরও ভাল" করে তোলে, আমিও ভাবছি কোন পরিস্থিতিতে এটি আরও খারাপ করে দেবে
ড্রু ডোরম্যান

2
@ ড্রুডোরম্যান, আমিও তাই ভাবছি। আমি নতুন বৈশিষ্ট্যগুলি ব্যবহার করতে পছন্দ করি তবে কখন সেগুলি ব্যবহার করতে হবে এবং কখন না তা খুব গুরুত্বপূর্ণ knowing এমন একটি সময় আছে যখন নতুন বৈশিষ্ট্য উদ্ভূত হয় যা আমরা এটি নির্ধারণ করি, সুতরাং আসুন এখনই এটি করা যাক যখন এটি আনুষ্ঠানিকভাবে আসে তখন আমরা প্রস্তুত থাকি :)
ক্রিস

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

1
@ নিকলবোলাস, যদি এটি সহায়তা করে তবে এটি এখনই গৃহীত হয়েছে: পি
ক্রিস

1
বর্তমান উত্তরগুলি উল্লেখ করে বলে মনে হয় না যে ->decltype(t+u)অটো ছাড়ের পরিবর্তে SFINAE কে হত্যা করা হয়।
মার্ক গ্লিস

উত্তর:


62

সি ++ 11 অনুরূপ প্রশ্ন উত্থাপন করে: ল্যাম্বডাসে কখন রিটার্ন টাইপ ছাড়ের ব্যবহার করতে হবে এবং কখন autoভেরিয়েবল ব্যবহার করতে হবে ।

C এবং C ++ 03 এ প্রশ্নের toতিহ্যবাহী উত্তরটি ছিল "বিবৃতি সীমানা জুড়ে আমরা প্রকারগুলি স্পষ্টভাবে প্রকাশ করি, প্রকাশের মধ্যে সেগুলি সাধারণত অন্তর্নিহিত হয় তবে আমরা তাদের বর্ণের সাথে স্পষ্ট করতে পারি"। সি ++ 11 এবং সি ++ 1 আই প্রকারের ছাড়ের সরঞ্জামগুলি প্রবর্তন করে যাতে আপনি প্রকারটি নতুন জায়গায় ছেড়ে যেতে পারেন।

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

যেহেতু "পাঠযোগ্যতা" নিখুঁতভাবে সংজ্ঞায়িত করা হয়নি [*], এবং তদ্ব্যতীত এটি পাঠকের দ্বারা পৃথক হয়, তাই কোনও অংশের কোডের লেখক / সম্পাদক হিসাবে আপনার একটি দায়িত্ব রয়েছে যা কোনও স্টাইল গাইড দ্বারা পুরোপুরি সন্তুষ্ট হতে পারে না। এমনকি শৈলীর নির্দেশিকা যে পরিমাণ নিয়মগুলি নির্দিষ্ট করে তার সীমা পর্যন্তও বিভিন্ন লোক বিভিন্ন মানদণ্ড পছন্দ করে এবং "কম পাঠযোগ্য" হতে অপরিচিত কিছু খুঁজে পাওয়ার ঝোঁক রাখে। সুতরাং নির্দিষ্ট প্রস্তাবিত শৈলীর নিয়মের পাঠযোগ্যতা কেবলমাত্র অন্যান্য স্টাইলের নিয়মগুলির প্রসঙ্গে কেবল বিচার করা যায়।

আপনার সমস্ত পরিস্থিতিতে (এমনকি প্রথমটি) কারও কোডিং শৈলীর জন্য ব্যবহার খুঁজে পাবেন। ব্যক্তিগতভাবে আমি সর্বাধিক আকর্ষণীয় ব্যবহারের কেস হিসাবে খুঁজে পাই, তবে তবুও আমি প্রত্যাশা করি যে এটি আপনার ডকুমেন্টেশন সরঞ্জামগুলির উপর নির্ভর করবে। কোনও ফাংশন টেম্প্লেটের রিটার্নের ধরনটি নথিভুক্ত দেখতে এটি খুব সহায়ক নয় auto, যদিও এটি নথিভুক্ত হিসাবে দেখা decltype(t+u)একটি প্রকাশিত ইন্টারফেস তৈরি করে যা আপনি বিশ্বাস করতে পারেন (আশা করি)।

[*] মাঝে মধ্যে কেউ কেউ কিছু উদ্দেশ্যমূলক পরিমাপ করার চেষ্টা করে। যে পরিমাণ পরিমিত পরিমাণে যে কোনও পরিসংখ্যানগতভাবে তাত্পর্যপূর্ণ এবং সাধারণভাবে প্রয়োগযোগ্য ফলাফল নিয়ে আসে, তারা "পাঠযোগ্য" কিসের বিষয়ে লেখকের প্রবৃত্তির পক্ষে, কর্মরত প্রোগ্রামারদের দ্বারা তারা সম্পূর্ণ উপেক্ষা করা হয়।


1
ল্যাম্বডাসের সংযোগগুলির জন্য ভাল পয়েন্ট (যদিও এটি আরও জটিল ফাংশন সংস্থাগুলির জন্য অনুমতি দেয়)। মূল বিষয়টি হ'ল এটি একটি নতুন বৈশিষ্ট্য এবং আমি এখনও প্রতিটি ব্যবহারের ক্ষেত্রে অনুকূল এবং স্বতন্ত্র সামঞ্জস্য করার চেষ্টা করছি। এটি করার জন্য, কেন এটির জন্য কীভাবে এটি ব্যবহার করা হবে তার পিছনে কারণগুলি দেখতে সহায়তা করা যাতে আমি নিজের কাজটি আমি কী করতে পছন্দ করি তা কেন আবিষ্কার করতে পারি। আমি এটি overth سوچ করা হতে পারে, কিন্তু আমি এইভাবে।
খ্রিস্ট

1
@ ক্রিস: যেমনটি আমি বলি, আমার মনে হয় এটি সমস্ত একই জিনিসটিতে নেমে আসে। আপনার কোডের পক্ষে "এই জিনিসের ধরণটি এক্স" বলা কি ভাল, বা আপনার কোডের পক্ষে এটি বলা ভাল, "এই জিনিসটির প্রকারটি অপ্রাসঙ্গিক, সংকলকটি জানা দরকার এবং আমরা সম্ভবত এটি কার্যকর করতে পারলাম তবে আমাদের এটি বলার দরকার নেই "। যখন আমরা লিখি 1.0 + 27Uআমরা উত্তরোত্তরকে দৃser়ভাবে বলছি, যখন আমরা লিখি (double)1.0 + (double)27Uআমরা পূর্ববর্তীটিকে দৃ .়ভাবে বলছি। ফাংশনটির সরলতা, নকলকরণের ডিগ্রি, এড়ানো decltypeসবই এতে অবদান রাখতে পারে তবে কোনওটি নির্ভরযোগ্যভাবে সিদ্ধান্ত নিতে পারে না।
স্টিভ জেসোপ

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

1
আমি যুক্ত করতে চাই যে আইডিইগুলি "পঠনযোগ্যতা সমস্যা" উপশম করতে পারে। উদাহরণস্বরূপ ভিজ্যুয়াল স্টুডিওটি ধরুন: আপনি autoকীওয়ার্ডের উপরে ঘুরে দেখলে এটি আসল রিটার্নের ধরণটি প্রদর্শন করবে।
andreee

1
@ অ্যান্ড্রি: সীমাবদ্ধতার মধ্যে এটি সত্য। যদি কোনও প্রকারের অনেকগুলি উপাধি থাকে তবে প্রকৃত প্রকারটি জানা আপনার আশা মতো সর্বদা কার্যকর নয়। উদাহরণ হিসেবে বলা যায় কোনো ইটারেটরে টাইপ হতে পারে int*, কিন্তু আসলে উল্লেখযোগ্য যে, কিছু হলে, যে কারণে এটি হয় int*কারণ যে কি std::vector<int>::iterator_typeআপনার বর্তমান বিল্ড বিকল্প সহ হয়!
স্টিভ জেসোপ

30

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

template<typename F, typename Tuple, int... I>
  auto
  apply_(F&& f, Tuple&& args, int_seq<I...>) ->
  decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...))
  {
    return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(args))...);
  }

template<typename F, typename Tuple,
         typename Indices = make_int_seq<std::tuple_size<Tuple>::value>>
  auto
  apply(F&& f, Tuple&& args) ->
  decltype(apply_(std::forward<F>(f), std::forward<Tuple>(args), Indices()))
  {
    return apply_(std::forward<F>(f), std::forward<Tuple>(args), Indices());
  }

এই উদাহরণটি অফিসিয়াল কমিটির কাগজ N3493 থেকে নেওয়া হয়েছে । ফাংশনের উদ্দেশ্য applyহ'ল ক এর উপাদানগুলিকে std::tupleএকটি ফাংশনে ফরোয়ার্ড করা এবং ফলাফলটি ফিরিয়ে দেওয়া। int_seqএবং make_int_seqবাস্তবায়ন একটি অংশ মাত্র, এবং সম্ভবত শুধুমাত্র বুঝতে এটি কী চেষ্টা যেকোনো ব্যবহারকারী গুলান হবে।

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

template <typename F, typename Tuple, size_t... I>
decltype(auto) apply_impl(F&& f, Tuple&& t, index_sequence<I...>) {
    return forward<F>(f)(get<I>(forward<Tuple>(t))...);
}

template <typename F, typename Tuple>
decltype(auto) apply(F&& f, Tuple&& t) {
    using Indices = make_index_sequence<tuple_size<decay_t<Tuple>>::value>;
    return apply_impl(forward<F>(f), forward<Tuple>(t), Indices{});
}

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


অন্য একটি বিষয় যা এখনও উল্লেখ করা হয়নি: SFINAE এক্সপ্রেশনটিdeclype(t+u) ব্যবহার করার অনুমতি দেয় , তা না করে (যদিও এই আচরণটি পরিবর্তনের প্রস্তাব রয়েছে )। উদাহরণস্বরূপ এমন একটি ফাংশন নিন যা কোনও টাইপের সদস্য ফাংশনটি উপস্থিত থাকলে কল করবে বা উপস্থিত থাকলে টাইপের সদস্য ফাংশনটি কল করবে এবং ধরে নিও যে কোনও শ্রেণীর সর্বদা যথাযথ বা উভয়ই একসাথে থাকে:decltype(auto)foobarfoobarfoobar

struct X
{
    void foo() const { std::cout << "foo\n"; }
};

struct Y
{
    void bar() const { std::cout << "bar\n"; }
};

template<typename C> 
auto foobar(const C& c) -> decltype(c.foo())
{
    return c.foo();
}

template<typename C> 
auto foobar(const C& c) -> decltype(c.bar())
{
    return c.bar();
}

কলিং foobarএর একটি দৃষ্টান্ত উপর Xপ্রদর্শন করা হবে fooযখন কলিং foobarএর একটি দৃষ্টান্ত উপর Yইচ্ছা প্রদর্শন bar। আপনি যদি এর পরিবর্তে (সাথে বা বাইরে decltype(auto)) স্বয়ংক্রিয় রিটার্নের ধরণের ছাড়টি ব্যবহার করেন তবে আপনি SFINAE এক্সপ্রেশন পাবেন না এবং এর foobarএকটি উদাহরণে কল করুন Xবা Yএকটি সংকলন-সময় ত্রুটি ট্রিগার করবে।


8

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

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


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

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

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

1
কমপক্ষে একটি পরিস্থিতি রয়েছে যেখানে এটি সমস্ত কিন্তু সম্পূর্ণ প্রয়োজনীয়। মনে করুন আপনাকে ফাংশনগুলি কল করতে হবে, তারপরে ফলাফলগুলি ফিরিয়ে দেওয়ার আগে লগ করুন এবং ফাংশনগুলির অগত্যা সমস্তরাই একই রকমের রিটার্ন টাইপ না করে। যদি আপনি এমন কোনও লগিং ফাংশনের মাধ্যমে করেন যা ফাংশনগুলি এবং তাদের আর্গুমেন্টগুলিকে পরামিতি হিসাবে গ্রহণ করে, তবে আপনাকে লগিং ফাংশনের রিটার্ন টাইপ ঘোষণা করতে autoহবে যাতে এটি সর্বদা পাস ফাংশনের রিটার্নের সাথে মেলে।
জাস্টিন সময় - মনিকা

1
[এটি করার জন্য প্রযুক্তিগতভাবে অন্য উপায় রয়েছে, তবে এটি মূলত একই জিনিসটি করতে টেমপ্লেট যাদু ব্যবহার করে autoএবং এরপরে ফিরে যাওয়ার ধরণের জন্য লগিং ফাংশনটি প্রয়োজন ]]
জাস্টিন সময় - মনিকা পুনরায়

7

ফাংশনের সরলতার সাথে এটি করার কিছুই নেই ( এই প্রশ্নের এখন-মুছে ফেলা ডুপ্লিকেট হিসাবে)।

হয় রিটার্নের ধরণটি স্থির (ব্যবহার করবেন না auto), বা কোনও টেম্পলেট প্যারামিটারের জটিল উপায়ে নির্ভর করে ( একাধিক রিটার্ন পয়েন্ট থাকলে autoবেশিরভাগ ক্ষেত্রে ব্যবহার করুন decltype) with


3

একটি আসল উত্পাদন পরিবেশ বিবেচনা করুন: অনেকগুলি ফাংশন এবং ইউনিট এর রিটার্নের ধরণের উপর নির্ভর করে সমস্ত আন্তঃনির্ভরশীল foo()। এখন ধরুন যে কোনও কারণে রিটার্নের ধরণটি পরিবর্তন করা দরকার।

যদি রিটার্নের ধরণ autoসর্বত্র থাকে এবং কলরগুলি foo()এবং সম্পর্কিত ফাংশনগুলি autoপ্রত্যাবর্তিত মান পাওয়ার সময় ব্যবহার করে তবে যে পরিবর্তনগুলি করা দরকার তা সর্বনিম্ন। যদি তা না হয় তবে এর অর্থ ঘন্টাগুলি অত্যন্ত ক্লান্তিকর এবং ত্রুটি-প্রবণ কাজ হতে পারে।

বাস্তব-বিশ্বের উদাহরণ হিসাবে, আমাকে সর্বত্র কাঁচা পয়েন্টার ব্যবহার থেকে স্মার্ট পয়েন্টারগুলিতে কোনও মডিউল পরিবর্তন করতে বলা হয়েছিল। ইউনিট পরীক্ষাগুলি স্থির করা প্রকৃত কোডের চেয়ে বেশি বেদনাদায়ক ছিল।

এটি পরিচালনা করতে পারে এমন অন্যান্য উপায় রয়েছে, তবে autoরিটার্নের ধরণের ব্যবহারগুলি বেশ উপযুক্ত বলে মনে হচ্ছে।


1
সেসব ক্ষেত্রে লেখালেখি করাই কি ভাল না decltype(foo())?
ওরেন এস

ব্যক্তিগতভাবে, আমি মনে করি এগুলি typedefএবং ওরফে ঘোষণাগুলি (যেমন usingপ্রকারের ঘোষণাপত্র) ভাল হয়, বিশেষত যখন তারা শ্রেণিবদ্ধ হয়।
MAChitgarha

3

আমি একটি উদাহরণ দিতে চাই যেখানে রিটার্ন টাইপ অটো নিখুঁত:

কল্পনা করুন আপনি দীর্ঘ পরবর্তী ক্রিয়াকলাপের জন্য একটি সংক্ষিপ্ত নাম তৈরি করতে চান। অটো দিয়ে আপনার মূল রিটার্নের ধরণের যত্ন নিতে হবে না (সম্ভবত এটি ভবিষ্যতে পরিবর্তিত হবে) এবং ব্যবহারকারী আসল রিটার্নের ধরন পেতে মূল ফাংশনে ক্লিক করতে পারেন:

inline auto CreateEntity() { return GetContext()->GetEntityManager()->CreateEntity(); }

পিএস: এই প্রশ্নের উপর নির্ভর করে ।


2

দৃশ্যের 3 এর জন্য আমি স্থানীয় ভেরিয়েবলটি ঘুরিয়ে ফিরতে ফাংশনের স্বাক্ষরের ফেরত টাইপ করব। এটি ক্লায়েন্ট প্রোগ্রামারদের ফাংশন রিটার্নের জন্য এটি আরও পরিষ্কার করে তুলবে। এটার মত:

পরিস্থিতি 3 অপ্রয়োজনীয়তা রোধ করতে:

std::vector<std::map<std::pair<int, double>, int>> foo() {
    decltype(foo()) ret;
    return ret;
}

হ্যাঁ, এর কোনও অটো কীওয়ার্ড নেই তবে অতিরিক্ত অর্থহীনতা রোধ করতে এবং উত্সটিতে অ্যাক্সেস নেই এমন প্রোগ্রামারদের দিতে প্রিন্সিপালটি একই।


2
আইএমও এর জন্য আরও ভাল সমাধান হ'ল এটি হিসাবে যেটিকে প্রতিনিধিত্ব করা vector<map<pair<int,double>,int>এবং তারপরে এটি ব্যবহার করার উদ্দেশ্যে যা কিছু আছে তার ধারণার জন্য একটি ডোমেন-নির্দিষ্ট নাম সরবরাহ করা ।
ডেভিডবাক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.