সহজ উত্তরটি হ'ল আপনার নিয়মিত রেফারেন্স কোডের মতো মূল্যবোধের রেফারেন্সের জন্য কোড লিখতে হবে এবং আপনার সময়কালের 99% মানসিকভাবে একই আচরণ করা উচিত। এর মধ্যে উল্লেখগুলি ফেরত দেওয়ার বিষয়ে পুরানো সমস্ত বিধি অন্তর্ভুক্ত রয়েছে (অর্থাত্ স্থানীয় ভেরিয়েবলের কোনও রেফারেন্স কখনই ফেরত পাবেন না)।
আপনি যদি কোনও টেম্পলেট ধারক শ্রেণীর লিখিত না লিখেন যার জন্য স্টাড :: ফরওয়ার্ডের সুবিধা নেওয়া দরকার এবং একটি জেনেরিক ফাংশন লিখতে সক্ষম হবেন যা উভয়ই ল্যাভালু বা মূল্যসূত্র রেফারেন্স গ্রহণ করে, এটি কমবেশি সত্য।
মুভ কনস্ট্রাক্টর এবং মুভ অ্যাসাইনমেন্টের বড় সুবিধাগুলির মধ্যে একটি হ'ল আপনি যদি এগুলি সংজ্ঞায়িত করেন তবে সংকলকগুলি সেগুলিতে আরভিও (রিটার্ন মান অপ্টিমাইজেশন) এবং এনআরভিও (নামযুক্ত রিটার্ন মান অপ্টিমাইজেশন) আহ্বানে ব্যর্থ হতে পারে use পদ্ধতিগুলি থেকে দক্ষতার সাথে মূল্য দিয়ে কনটেইনার এবং স্ট্রিংয়ের মতো ব্যয়বহুল জিনিসগুলি ফেরত দেওয়ার জন্য এটি বেশ বিশাল।
এখন যেখানে জিনিসগুলি মূল্যের রেফারেন্স সহ আকর্ষণীয় হয়ে ওঠে, তা হ'ল আপনি এগুলিকে সাধারণ ক্রিয়াকলাপের পক্ষে যুক্তি হিসাবেও ব্যবহার করতে পারেন। এটি আপনাকে কনটেইনারগুলি লিখতে অনুমতি দেয় যা উভয় কনস্ট কনফারেন্স (কনস্ট ফু এবং অন্যান্য) এবং মূল্যসূত্র রেফারেন্স (ফু ও এন্ড অন্যান্য) এর জন্য ওভারলোড রয়েছে। এমনকি যদি যুক্তিটি কেবল অনর্থক হলেও কেবল নির্মাতা কল দিয়ে তা পাস করা যায় না:
std::vector vec;
for(int x=0; x<10; ++x)
{
// automatically uses rvalue reference constructor if available
// because MyCheapType is an unamed temporary variable
vec.push_back(MyCheapType(0.f));
}
std::vector vec;
for(int x=0; x<10; ++x)
{
MyExpensiveType temp(1.0, 3.0);
temp.initSomeOtherFields(malloc(5000));
// old way, passed via const reference, expensive copy
vec.push_back(temp);
// new way, passed via rvalue reference, cheap move
// just don't use temp again, not difficult in a loop like this though . . .
vec.push_back(std::move(temp));
}
এসটিএল পাত্রে প্রায় কোনও কিছুর (হ্যাশ কী এবং মান, ভেক্টর সন্নিবেশ ইত্যাদি) সরানোর জন্য ওভারলোডগুলি আপডেট করা হয়েছে এবং যেখানে আপনি সেগুলি সর্বাধিক দেখতে পাবেন।
আপনি এগুলিকে সাধারণ ক্রিয়াকলাপেও ব্যবহার করতে পারেন এবং যদি আপনি কেবল কোনও মূল্যায়ণ রেফারেন্স যুক্তি সরবরাহ করেন তবে আপনি কলারকে অবজেক্টটি তৈরি করতে বাধ্য করতে পারেন এবং ফাংশনটি চলতে দিন। এটি সত্যিই ভাল ব্যবহারের চেয়ে উদাহরণের চেয়ে বেশি, তবে আমার রেন্ডারিং লাইব্রেরিতে আমি সমস্ত লোড হওয়া সংস্থানগুলিতে একটি স্ট্রিং বরাদ্দ করেছি, যাতে প্রতিটি বস্তু ডিবাগারে কী উপস্থাপন করে তা দেখতে আরও সহজ। ইন্টারফেসটি এরকম কিছু:
TextureHandle CreateTexture(int width, int height, ETextureFormat fmt, string&& friendlyName)
{
std::unique_ptr<TextureObject> tex = D3DCreateTexture(width, height, fmt);
tex->friendlyName = std::move(friendlyName);
return tex;
}
এটি একটি 'ফাঁসী বিমূর্ততা' এর একটি রূপ তবে আমাকে ইতিমধ্যে বেশিরভাগ সময় স্ট্রিংটি তৈরি করতে হয়েছিল এবং আমি এটির আর একটি অনুলিপি করা এড়াতে সক্ষম হওয়ার সুযোগটি নিতে পারি। এটি হুবহু উচ্চ-সম্পাদনকারী কোড নয় তবে লোকেরা এই বৈশিষ্ট্যটির হ্যাং পাওয়ায় সম্ভাবনার একটি ভাল উদাহরণ। এই কোডটির আসলে প্রয়োজন হয় যে ভেরিয়েবলটি কলটির জন্য অস্থায়ী হয়, বা std :: পদক্ষেপ গ্রহণ করা হয়:
// move from temporary
TextureHandle htex = CreateTexture(128, 128, A8R8G8B8, string("Checkerboard"));
অথবা
// explicit move (not going to use the variable 'str' after the create call)
string str("Checkerboard");
TextureHandle htex = CreateTexture(128, 128, A8R8G8B8, std::move(str));
অথবা
// explicitly make a copy and pass the temporary of the copy down
// since we need to use str again for some reason
string str("Checkerboard");
TextureHandle htex = CreateTexture(128, 128, A8R8G8B8, string(str));
কিন্তু এটি সংকলন হবে না!
string str("Checkerboard");
TextureHandle htex = CreateTexture(128, 128, A8R8G8B8, str);