লুপের জন্য পরিসীমা ভিত্তিক ফরওয়ার্ডিং রেফারেন্সগুলি ব্যবহার করে কী সুবিধা হবে?


115

const auto&আমি কেবল পঠনযোগ্য ক্রিয়াকলাপ সম্পাদন করতে চাইলে যথেষ্ট হবে। তবে আমি bুকে পড়েছি

for (auto&& e : v)  // v is non-const

সম্প্রতি কয়েকবার। এটি আমাকে অবাক করে তোলে:

এটা কি সম্ভব যে কিছু অস্পষ্ট কোণার ক্ষেত্রে ফরওয়ার্ডিং রেফারেন্সগুলি ব্যবহার করার ক্ষেত্রে কিছুটা পারফরম্যান্স সুবিধা রয়েছে auto&বা এর তুলনায় const auto&?

( shared_ptrঅস্পষ্ট কোণার ক্ষেত্রে সন্দেহজনক)


আমার প্রিয়তে পাওয়া দুটি উদাহরণ আপডেট করুন :

মৌলিক ধরণের উপর পুনরাবৃত্তি যখন কনস্ট্যান্ড রেফারেন্স ব্যবহার করে কোন অসুবিধা?
লুপের জন্য একটি পরিসীমা-ভিত্তিক ব্যবহার করে আমি কী সহজেই মানচিত্রের মানগুলি নিয়ে পুনরাবৃত্তি করতে পারি?

দয়া করে এই প্রশ্নটিতে মনোনিবেশ করুন: আমি লুপগুলির জন্য কেন পরিসীমা ভিত্তিতে অটো এবং& ব্যবহার করতে চাই?


4
আপনি কি সত্যিই এটি "প্রায়শই" দেখেন?
অরবিটে লাইটনেস রেস

2
আমি নিশ্চিত নই যে আপনার প্রশ্নে আমার যথেষ্ট পরিমাণের প্রসঙ্গ আছে যেখানে আপনি এটি দেখছেন সেখানে কতটা "পাগল" তা অনুমান করার জন্য।
অরবিটে লাইটনেস রেস

2
@ লাইটনেসেসেসিনআরবিত দীর্ঘ গল্পের ছোট গল্প: আমি auto&&লুপগুলির জন্য কেন রেঞ্জ-ভিত্তিক ব্যবহার করতে চাই ?
আলী

উত্তর:


94

কেবলমাত্র আমি দেখতে পাচ্ছি যখন সিকোয়েন্স পুনরাবৃত্তিকারীরা প্রক্সি রেফারেন্স দেয় এবং আপনাকে সেই রেফারেন্সটি অ-স্থিরভাবে পরিচালনা করতে হবে। উদাহরণস্বরূপ বিবেচনা করুন:

#include <vector>

int main()
{
    std::vector<bool> v(10);
    for (auto& e : v)
        e = true;
}

এটি সংকলন করে না কারণ মানগুলি vector<bool>::referenceথেকে প্রত্যাবর্তনটি iteratorকোনও নন-কনস্ট্যান্ট লভালু রেফারেন্সকে আবদ্ধ করবে না। তবে এটি কাজ করবে:

#include <vector>

int main()
{
    std::vector<bool> v(10);
    for (auto&& e : v)
        e = true;
}

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

#include <vector>

int main()
{
    std::vector<bool> v(10);
    // using auto&& so that I can handle the rvalue reference
    //   returned for the vector<bool> case
    for (auto&& e : v)
        e = true;
}

সম্পাদন করা

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


3
অন্যদিকে, এর কোনও স্পষ্ট অসুবিধা নেই , আছে কি? (সম্ভাব্য বিভ্রান্ত ব্যক্তিদের পাশাপাশি, যা আমি ব্যক্তিগতভাবে উল্লেখ করার মতো মনে করি না))
iljarn

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

7
আমি পছন্দ করি const auto&যখন আমি সংকলকটি আমাকে ক্রমশ ক্রমে উপাদানগুলি সংশোধন না করে তা পরীক্ষা করতে সহায়তা করতে চাই to
হাওয়ার্ড হিন্যান্ট

31
আমি ব্যক্তিগতভাবে auto&&জেনেরিক কোডটি ব্যবহার করতে চাই যেখানে আমাকে ক্রমের উপাদানগুলি সংশোধন করতে হবে। যদি আমি না করি তবে আমি কেবল আঁকড়ে থাকব auto const&
Xoo

7
@ শিও: +1 এটি নিজের মতো উত্সাহীদের কারণে, নিয়মিত পরীক্ষা-নিরীক্ষা করা এবং কাজ করার আরও ভাল উপায়ের জন্য চাপ দেওয়া, যা সি ++ অবিরত অবিরত থাকে। ধন্যবাদ. :-)
হাওয়ার্ড হিন্যান্ট

26

রেঞ্জ-ভিত্তিক- লুপের সাথে সর্বজনীন রেফারেন্সগুলি ব্যবহার করা auto&&বা আপনি যেটি পান সেটি ক্যাপচার করার সুবিধা রয়েছে। বেশিরভাগ ধরণের পুনরাবৃত্তির জন্য আপনি সম্ভবত কিছু প্রকারের জন্য একটি বা একটি পাবেন । মজার ঘটনাটি হ'ল যেখানে একজন পুনরুক্তিকারীকে ডিফারেন্ট করার মাধ্যমে একটি অস্থায়ী ফল পাওয়া যায়: সি ++ 2011 স্বাচ্ছন্দ্যের প্রয়োজনীয়তা পেয়েছে এবং পুনরুক্তি করার জন্য আবশ্যিকভাবে আবশ্যকীয় প্রয়োজন হয় না। সর্বজনীন রেফারেন্সের ব্যবহার যুক্তিটির ফরোয়ার্ডিংয়ের সাথে মেলে :forT&T const&Tstd::for_each()

template <typename InIt, typename F>
F std::for_each(InIt it, InIt end, F f) {
    for (; it != end; ++it) {
        f(*it); // <---------------------- here
    }
    return f;
}

ফাংশন বস্তুর fচিকিৎসা করতে পারে T&, T const&এবং Tভিন্নভাবে। রেঞ্জ-ভিত্তিক- forলুপের বডি কেন পৃথক হওয়া উচিত ? অবশ্যই, সর্বজনীন রেফারেন্সগুলি ব্যবহার করে টাইপটি কমিয়ে আনার সুবিধাটি গ্রহণ করার জন্য আপনার এটিকে যথাযথভাবে পাস করতে হবে:

for (auto&& x: range) {
    f(std::forward<decltype(x)>(x));
}

অবশ্যই, ব্যবহারের std::forward()অর্থ হ'ল আপনি যে কোনও প্রত্যাবর্তিত মানগুলি থেকে সরিয়ে নেওয়া গ্রহণ করেন। আমি জানি না এমন (টেমপ্লেট কোড) নমনীয় কোডগুলিতে এর মতো বস্তুগুলি বেশি অর্থবোধ করে কিনা। আমি কল্পনা করতে পারি যে সর্বজনীন রেফারেন্সগুলি ব্যবহার করে সঠিক কাজটি করার জন্য সংকলকটিকে আরও তথ্যের প্রস্তাব দেওয়া যেতে পারে। টেম্পলেটেড কোডে এটি অবজেক্টগুলির সাথে কী ঘটবে সে সম্পর্কে কোনও সিদ্ধান্ত নেওয়ার বাইরে থেকে যায়।


9

আমি কার্যত সর্বদা ব্যবহার auto&&। যখন আপনার দরকার নেই তখন কেন একটি কিনারায় কেটে যাবে? এটিও টাইপ করা সংক্ষিপ্ত এবং আমি কেবল এটি আরও ... স্বচ্ছ দেখতে পাই। আপনি যখন ব্যবহার করবেন auto&& x, তখন আপনি জানবেন যে xএটি ঠিক *it, প্রতিটি সময়,


29
আমার সমস্যা আপনার ছোড় হয় constসঙ্গে -ness auto&&যদি const auto&যথেষ্ট। প্রশ্নটি কর্নার মামলাগুলির জন্য জিজ্ঞাসা করে যেখানে আমি কামড়াতে পারি। এমন কোন কোন কোন বিষয়গুলি যা ডায়িতমার বা হাওয়ার্ড দ্বারা এখনও উল্লেখ করা হয়নি?
আলী

2
আপনি যদি এটি ব্যবহার করেন তবে কামড়ানোর একটি উপায় auto&&। আপনি যে ধরণের ক্যাপচার করছেন সেটি লুপের শৃঙ্খলে (উদাহরণস্বরূপ) সরানো উচিত এবং পরে পরিবর্তিত হওয়া উচিত যাতে এটি কোনও const&ধরণের সমাধান হয় , আপনার কোডটি নিঃশব্দে কাজ করা চালিয়ে যাবে, তবে আপনার পদক্ষেপের অনুলিপি আসবে। এই কোডটি খুব প্রতারণামূলক হবে। তবে, আপনি যদি ধরণের স্পষ্টভাবে একটি আর-মান উল্লেখ হিসাবে উল্লেখ করেন তবে যেই ধারক প্রকারটি পরিবর্তন করেছে সে একটি সংকলন ত্রুটি পাবে কারণ আপনি সত্যই সত্যই এই জিনিসগুলি সরানো চেয়েছিলেন এবং অনুলিপি করেছিলেন ...
সাইবারবিসন

@cyberbisson আমি সবেমাত্র এটিকে দেখতে পেয়েছি: স্পষ্টভাবে ধরণটি নির্দিষ্ট করে না দিয়ে কীভাবে আমি কোনও মূল্যায়ন রেফারেন্স প্রয়োগ করতে পারি? এরকম কিছু for (std::decay_t<decltype(*v.begin())>&& e: v)? আমার মনে হয় এর থেকে আরও ভাল উপায় আছে ...
জেরি মা

@ জেরিমা এটি টাইপ সম্পর্কে আপনি কী জানেন তা নির্ভর করে । উপরে উল্লিখিত হিসাবে, auto&&একটি "সর্বজনীন রেফারেন্স" দেবে, সুতরাং এগুলি ব্যতীত অন্য যে কোনও কিছু আপনাকে আরও সুনির্দিষ্ট ধরণের দেয়। যদি vএকটি হিসাবে ধরে নেওয়া হয় vector, আপনি করতে পারেন decltype(v)::value_type&&, যা আমি অনুমান করি যে আপনি operator*পুনরাবৃত্তকারীর ধরণের ফলাফল গ্রহণ করে আপনি চেয়েছিলেন । আপনি decltype(begin(v))::value_type&&ধারকটির পরিবর্তে পুনরাবৃত্তির ধরণগুলি পরীক্ষা করতে পারেন । এই ধরণের যদি আমাদের কাছে খুব সামান্য অন্তর্দৃষ্টি থাকে তবে আমরা কেবল auto&&
এটির
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.