এটি একটি মূল রেফারেন্স ঘোষণা করে (মান প্রস্তাব নথি) proposal
মূল্যবোধের রেফারেন্সগুলির একটি ভূমিকা এখানে ।
মাইক্রোসফ্টের স্ট্যান্ডার্ড লাইব্রেরি বিকাশকারীদের একজনের যথাযথ রেফারেন্সগুলিতে এক গভীরভাবে গভীর চেহারা ।
সতর্কতা: এমএসডিএন সম্পর্কিত লিঙ্কিত নিবন্ধ ("মূল্যায়ন রেফারেন্স: ভিসি 10-তে সি ++ 0x বৈশিষ্ট্যসমূহ, পার্ট 2") মূল্যবোধের রেফারেন্সগুলির একটি খুব সুস্পষ্ট পরিচয়, তবে সি ++ 11 খসড়ার ক্ষেত্রে সত্য যে রেভেলু রেফারেন্সগুলি ছিল তা সম্পর্কে বিবৃতি দেয় makes মান, কিন্তু চূড়ান্ত এক জন্য সত্য নয়! বিশেষত, এটি বিভিন্ন পয়েন্টে বলেছে যে মূল্যের রেফারেন্সগুলি লভ্যুয়ালের সাথে আবদ্ধ হতে পারে, যা একসময় সত্য ছিল তবে পরিবর্তিত হয়েছিল eg (উদাহরণস্বরূপ int x; int && rrx = x; আর জিসিসিতে আর সংকলন করা হয় না) - জুলাই 13 '14 এ 16 ডিসেম্বর
একটি C ++ 03 রেফারেন্সের মধ্যে সর্বাধিক পার্থক্য (বর্তমানে সি ++ 11-এ একটি ল্যাভেলু রেফারেন্স বলা হয়) এটি কনস্টের হওয়া ছাড়াই অস্থায়ীর মতো কোনও মূল্যকে আবদ্ধ করতে পারে। সুতরাং, এই বাক্য গঠনটি এখন আইনী:
T&& r = T();
মূলসূত্র উল্লেখগুলি নিম্নলিখিতগুলির জন্য প্রাথমিকভাবে সরবরাহ করে:
শব্দার্থক সরান । একটি মুভ কনস্ট্রাক্টর এবং মুভ অ্যাসাইনমেন্ট অপারেটরকে এখন সংজ্ঞায়িত করা যেতে পারে যা সাধারণ কনস্ট-লভ্যালু রেফারেন্সের পরিবর্তে একটি রেউলিউ রেফারেন্স নেয়। উত্সটি অপরিবর্তিত রাখতে বাধ্য নয় তবে একটি অনুলিপিটির মতো একটি পদক্ষেপ কাজ করে; প্রকৃতপক্ষে, এটি সাধারণত উত্সটি এমনভাবে সংশোধন করে যে এটি আর স্থানান্তরিত সংস্থাগুলির মালিক নয়। বহিরাগত অনুলিপিগুলি মুছে ফেলার জন্য এটি দুর্দান্ত, বিশেষত স্ট্যান্ডার্ড লাইব্রেরি বাস্তবায়নে।
উদাহরণস্বরূপ, একটি অনুলিপি নির্মাণকারী দেখতে দেখতে এটি দেখতে পাবেন:
foo(foo const& other)
{
this->length = other.length;
this->ptr = new int[other.length];
copy(other.ptr, other.ptr + other.length, this->ptr);
}
যদি এই কনস্ট্রাক্টরকে অস্থায়ীভাবে পাস করা হয়, তবে অনুলিপিটি অপ্রয়োজনীয় হবে কারণ আমরা জানি অস্থায়ী মাত্র ধ্বংস হয়ে যাবে; ইতিমধ্যে বরাদ্দ থাকা সংস্থাগুলি কেন ব্যবহার করবেন না? সি ++ তে, অনুলিপি প্রতিরোধের কোনও উপায় নেই কারণ আমরা নির্ধারণ করতে পারি না যে আমরা অস্থায়ী হয়েছি। সি ++ 11 এ আমরা একটি মুভ কনস্ট্রাক্টরকে ওভারলোড করতে পারি:
foo(foo&& other)
{
this->length = other.length;
this->ptr = other.ptr;
other.length = 0;
other.ptr = nullptr;
}
এখানে বড় পার্থক্য লক্ষ্য করুন: মুভ কনস্ট্রাক্টর তার যুক্তিটি সংশোধন করে। এটি কার্যকরভাবে তৈরি করা অবজেক্টটিতে অস্থায়ীভাবে "সরানো" হবে, যার ফলে অপ্রয়োজনীয় অনুলিপি দূর হবে।
মুভ কনস্ট্রাক্টরটি অস্থায়ী এবং নন-কনস্ট্যান্ট লভ্যালু রেফারেন্সগুলির জন্য ব্যবহৃত হত যা স্পষ্টভাবে std::move
ফাংশনটি ব্যবহার করে মূল্যসূত্র রেফারেন্সে রূপান্তরিত হয় (এটি কেবল রূপান্তর সম্পাদন করে)। নিম্নলিখিত কোড উভয়ের জন্য পদক্ষেপ কন্সট্রাকটর ডাকা f1
এবং f2
:
foo f1((foo())); // Move a temporary into f1; temporary becomes "empty"
foo f2 = std::move(f1); // Move f1 into f2; f1 is now "empty"
পারফেক্ট ফরওয়ার্ডিং । মূল্যসূচক উল্লেখগুলি টেম্পলেটড ফাংশনগুলির জন্য যুক্তিগুলি যথাযথভাবে ফরোয়ার্ড করতে দেয়। উদাহরণস্বরূপ এই কারখানার কার্যকারিতাটি ধরুন:
template <typename T, typename A1>
std::unique_ptr<T> factory(A1& a1)
{
return std::unique_ptr<T>(new T(a1));
}
যদি আমরা ডাকা হয় factory<foo>(5)
, আর্গুমেন্টটি অনুমান করা হবে int&
, যা কোনও আক্ষরিক 5 এর সাথে আবদ্ধ হবে না, এমনকি যদি foo
তার নির্মাণকারী একটি নেয় int
। ঠিক আছে, আমরা পরিবর্তে ব্যবহার করতে পারি A1 const&
, তবে কি যদি foo
কনস্ট্রাক্টর নন-কনস্ট্যান্ট রেফারেন্স দ্বারা যুক্তিটি গ্রহণ করা হয়? সত্যিকারের জেনেরিক কারখানা ফাংশন করতে, আমরা ফ্যাক্টরি জমিদার করতে হবে A1&
এবং এর A1 const&
। কারখানাটি যদি 1 টি প্যারামিটারের ধরণ নেয় তবে এটি সূক্ষ্ম হতে পারে, তবে প্রতিটি অতিরিক্ত পরামিতি টাইপ 2 দ্বারা প্রয়োজনীয় ওভারলোড সেটটি গুণ করে। এটি খুব তাড়াতাড়ি কল্পনাযোগ্য নয়।
মান সংক্রান্ত রেফারেন্সগুলি স্ট্যান্ডার্ড লাইব্রেরিটিকে কোনও std::forward
ফাংশন সংজ্ঞায়িত করার অনুমতি দেয় যা সঠিকভাবে ল্যাভালু / রেভ্যালু রেফারেন্সগুলি ফরোয়ার্ড করতে পারে। কীভাবে std::forward
কাজ করে সে সম্পর্কে আরও তথ্যের জন্য , এই দুর্দান্ত উত্তরটি দেখুন ।
এটি আমাদের মত কারখানার কার্যকারিতা সংজ্ঞায়িত করতে সক্ষম করে:
template <typename T, typename A1>
std::unique_ptr<T> factory(A1&& a1)
{
return std::unique_ptr<T>(new T(std::forward<A1>(a1)));
}
এখন কনস্ট্রাক্টরের কাছে পাঠানোর সময় আর্গুমেন্টের মূল্য / লভ্যালু-নেস সংরক্ষণ করা হয় T
। এর অর্থ হ'ল যদি কারখানাকে কোনও মূল্য দিয়ে কল করা হয় তবে T
এর নির্মাতাকে একটি মূল্য দিয়ে ডাকা হয়। যদি কারখানাকে ল্যাভ্যু দিয়ে ডাকা হয় তবে T
এর নির্মাণকারীকে একটি ল্যাভ্যু দিয়ে ডাকা হয়। উন্নত কারখানার কাজ একটি বিশেষ নিয়মের কারণে কাজ করে:
যখন ফাংশন প্যারামিটার প্রকার ফর্ম হল T&&
যেখানে T
একটি টেমপ্লেট প্যারামিটার হয়, এবং ফাংশন যুক্তি প্রকারের একটি lvalue হয় A
, টাইপ A&
টেমপ্লেট যুক্তি সিদ্ধান্তগ্রহণ জন্য ব্যবহৃত হয়।
সুতরাং, আমরা যেমন কারখানা ব্যবহার করতে পারেন:
auto p1 = factory<foo>(foo()); // calls foo(foo&&)
auto p2 = factory<foo>(*p1); // calls foo(foo const&)
গুরুত্বপূর্ণ মূল্যসূচক রেফারেন্স বৈশিষ্ট্য :
- ওভারলোড রেজোলিউশনের জন্য, ল্যাভেলুগুলি লভ্যালু রেফারেন্সগুলিকে বাধ্যতামূলক পছন্দ করে এবং মূল্যগুলি রেভ্যালু রেফারেন্সের সাথে বাধ্যতামূলক পছন্দ করে । সুতরাং টেম্পোরারিগুলি কেন একটি অনুলিপি নির্মাণকারী / অ্যাসাইনমেন্ট অপারেটরের উপর একটি মুভ কনস্ট্রাক্টর / মুভ এসাইনমেন্ট অপারেটরকে অনুরোধ করতে পছন্দ করে।
- মূলসূত্র উল্লেখগুলি অন্তর্নিহিত রূপান্তরগুলির ফলস্বরূপ মূল্যবোধ এবং অস্থায়ী সংস্থাগুলির সাথে আবদ্ধ হবে । অর্থাত্
float f = 0f; int&& i = f;
সুগঠিত হয় কারণ ভাসাটি নিখুঁতভাবে ইন-তে রূপান্তরিত হয়; রেফারেন্সটি একটি অস্থায়ী সম্পর্কে হবে যা রূপান্তরটির ফলাফল।
- নামযুক্ত মূল্যসূত্র উল্লেখগুলি হ'ল মূল্য। নামবিহীন মূল্যসূচক উল্লেখগুলি হল মূল্যবোধ val কেন
std::move
কলটি প্রয়োজনীয় তা বুঝতে এটি গুরুত্বপূর্ণ :foo&& r = foo(); foo f = std::move(r);