auto&& var = <initializer>
আপনি যা বলছেন তা ব্যবহার করে : আমি যে কোনও প্রাথমিককরণ গ্রহণ করবো তা নির্বিশেষে এটি লভ্যালু বা মূল্যমানের অভিব্যক্তি এবং আমি এর দৃ const়তা রক্ষা করব । এটি সাধারণত ফরওয়ার্ডিংয়ের জন্য ব্যবহৃত হয় (সাধারণত সাথে T&&
)। এই কাজ করার কারণটি হ'ল একটি "সার্বজনীন রেফারেন্স", auto&&
বা T&&
যে কোনও কিছুর সাথে আবদ্ধ হবে ।
আপনি বলতে পারেন, ভাল কেন কেবল একটি ব্যবহার করবেন না const auto&
কারণ এটি কোনও কিছুর সাথেও আবদ্ধ হবে ? const
রেফারেন্স ব্যবহার করে সমস্যা হচ্ছে এটি const
! আপনি পরে এটি কোনও নিরপেক্ষ রেফারেন্সের সাথে আবদ্ধ করতে পারবেন না বা চিহ্নিত নয় এমন কোনও সদস্য ফাংশন প্রার্থনা করতে পারবেন না const
।
উদাহরণস্বরূপ, কল্পনা করুন যে আপনি একটি পেতে চান std::vector
, এটির প্রথম উপাদানটিতে একটি পুনরুক্তিকারককে নিয়ে যান এবং সেই পুনরুক্তিকারীটির দ্বারা নির্দেশিত মানটি কোনও উপায়ে সংশোধন করুন:
auto&& vec = some_expression_that_may_be_rvalue_or_lvalue;
auto i = std::begin(vec);
(*i)++;
এই কোডটি প্রাথমিক সূচকটি নির্বিশেষে ঠিক সূক্ষ্ম সংকলন করবে। auto&&
নিম্নলিখিত উপায়ে ব্যর্থ বিকল্পগুলি :
auto => will copy the vector, but we wanted a reference
auto& => will only bind to modifiable lvalues
const auto& => will bind to anything but make it const, giving us const_iterator
const auto&& => will bind only to rvalues
সুতরাং এই জন্য, auto&&
পুরোপুরি কাজ করে! এর auto&&
মতো ব্যবহারের উদাহরণ একটি ব্যাপ্তি-ভিত্তিক for
লুপে রয়েছে। দেখুন আমার অন্যান্য প্রশ্ন আরো বিস্তারিত জানার জন্য।
তারপরে আপনি যদি std::forward
আপনার auto&&
রেফারেন্সটি ব্যবহার করে এই সত্যটি সংরক্ষণ করেন যে এটি মূলত একটি মূল্যমান বা মূল্যমান ছিল, আপনার কোড বলে: এখন যেহেতু আমি আপনার অবজেক্টটি কোনও ল্যাভালু বা মূল্যবোধের এক্সপ্রেশন থেকে পেয়েছি, আমি মূলত যে কোনও মূল্যবোধ সংরক্ষণ করতে চাই ছিল তাই আমি এটি সবচেয়ে দক্ষতার সাথে ব্যবহার করতে পারি - এটি এটিকে অকার্যকর করতে পারে। যেমন:
auto&& var = some_expression_that_may_be_rvalue_or_lvalue;
// var was initialized with either an lvalue or rvalue, but var itself
// is an lvalue because named rvalues are lvalues
use_it_elsewhere(std::forward<decltype(var)>(var));
এর ফলে use_it_elsewhere
কর্মক্ষমতা (এড়ানো কপি) অনুরোধে জন্য তার সাহস আউট চেরা যখন মূল সূচনাকারী একটি সংশোধনযোগ্য rvalue ছিল।
এর অর্থ কী বা আমরা যখন থেকে সম্পদ চুরি করতে পারি তার অর্থ কী var
? ভাল যেহেতু যে auto&&
কোনও কিছুর সাথে আবদ্ধ হবে, আমরা সম্ভবত var
নিজের সাহসিকতাগুলি ছিনিয়ে নেওয়ার চেষ্টা করতে পারি না - এটি খুব ভাল দামের বা এমনকি কনস্টও হতে পারে। তবে আমরা std::forward
এটি অন্যান্য ক্রিয়াকলাপগুলিতে করতে পারি যা এর অভ্যন্তরের অভ্যন্তরে সম্পূর্ণরূপে সর্বনাশ করতে পারে। var
এটি করার সাথে সাথে আমাদের একটি অবৈধ অবস্থায় থাকা উচিত an
এখন আসুন auto&& var = foo();
আপনার প্রশ্নে যেমনটি দেওয়া হয়েছে, যেখানে foo T
মান অনুসারে একটি ফেরত দেয় সেই ক্ষেত্রে এটি প্রয়োগ করুন । এই ক্ষেত্রে আমরা নিশ্চিতভাবে জানি যে প্রকারটি var
হ্রাস করা হবে T&&
। যেহেতু আমরা নিশ্চিতভাবে জানি যে এটি একটি মূল্যবান, তাই std::forward
এর সংস্থানগুলি চুরি করার জন্য আমাদের অনুমতি লাগবে না । এই নির্দিষ্ট ক্ষেত্রে, মূল্য অনুসারে রিটার্ন জেনেfoo
পাঠকের কেবল এটি পড়তে হবে: আমি যে অস্থায়ী থেকে ফিরে এসেছি তার একটি মূল্যবান রেফারেন্স নিচ্ছি foo
, তাই আমি খুশি হয়ে এ থেকে সরে যেতে পারি।
সংযোজন হিসাবে, আমি মনে করি এটি উল্লেখ করার উপযুক্ত যখন some_expression_that_may_be_rvalue_or_lvalue
একটি "ওয়েল আপনার কোডটি পরিবর্তিত হতে পারে" পরিস্থিতি ব্যতীত অন্য মত প্রকাশ হতে পারে। সুতরাং এখানে একটি স্বতন্ত্র উদাহরণ:
std::vector<int> global_vec{1, 2, 3, 4};
template <typename T>
T get_vector()
{
return global_vec;
}
template <typename T>
void foo()
{
auto&& vec = get_vector<T>();
auto i = std::begin(vec);
(*i)++;
std::cout << vec[0] << std::endl;
}
এখানে, get_vector<T>()
সেই মনোরম অভিব্যক্তি যা জেনেরিক ধরণের উপর নির্ভর করে লভালু বা মূল্যমান হতে পারে T
। আমরা get_vector
টেম্পলেট প্যারামিটারের মাধ্যমে মূলত রিটার্নের ধরণটি পরিবর্তন করি foo
।
আমরা যখন কল foo<std::vector<int>>
, get_vector
ফিরে আসবে global_vec
মান, যা একটি rvalue অভিব্যক্তি দেয় দ্বারা। অন্যথা, যখন আমরা কল foo<std::vector<int>&>
, get_vector
ফিরে আসবে global_vec
, রেফারেন্স দ্বারা একটি lvalue অভিব্যক্তি ফলে।
আমরা যদি:
foo<std::vector<int>>();
std::cout << global_vec[0] << std::endl;
foo<std::vector<int>&>();
std::cout << global_vec[0] << std::endl;
আমরা প্রত্যাশিত হিসাবে নিম্নলিখিত আউটপুট পেতে:
2
1
2
2
আপনি পরিবর্তন করতে হলে auto&&
কোন কোডে auto
, auto&
, const auto&
, অথবা const auto&&
তারপর আমরা ফলাফলের আমরা চাই পাবেন না।
আপনার auto&&
রেফারেন্সটি কোনও মূল্যবান বা মূল্যবান এক্সপ্রেশন দিয়ে আরম্ভ করা হয়েছে তার উপর ভিত্তি করে প্রোগ্রাম যুক্তি পরিবর্তন করার বিকল্প উপায় হ'ল ধরণের বৈশিষ্ট্য ব্যবহার করা:
if (std::is_lvalue_reference<decltype(var)>::value) {
// var was initialised with an lvalue expression
} else if (std::is_rvalue_reference<decltype(var)>::value) {
// var was initialised with an rvalue expression
}
auto&&
? আমি লুপের জন্য একটি পরিসীমা-ভিত্তিকauto&&
উদাহরণ হিসাবে ব্যবহারের জন্য কেন বিস্তৃত হয় তা দেখার চিন্তা করেছিলাম , তবে এটির সাথে এটি আর পায়নি। সম্ভবত যে উত্তর দেয় সে এটি ব্যাখ্যা করতে পারে।