এখানে ইস্যু যে যেহেতু হয়, বর্গ উপর টেমপ্লেট করা হয় Tকন্সট্রাকটর এ, Foo(T&&)আমরা না করণ টাইপ সিদ্ধান্তগ্রহণ; আমাদের সবসময়ই একটি আর-মান রেফারেন্স থাকে। এটি হ'ল, Fooনির্মাতা প্রকৃতপক্ষে এর মতো দেখায়:
Foo(int&&)
Foo(2)কাজ কারণ 2একটি মূল্য আছে।
Foo(x)না কারণ xএটি এমন একটি মূল্যমান যা আবদ্ধ হতে পারে না int&&। আপনি std::move(x)এটি উপযুক্ত ধরণের ( ডেমো ) কাস্ট করতে পারেন
Foo<int&>(x)ঠিকঠাক কাজ করে কারণ কনস্ট্রাক্টর Foo(int&)রেফারেন্স বিধ্বস্ত হওয়ার কারণে হয়ে যায় ; প্রাথমিকভাবে এটি স্ট্যান্ডার্ড অনুযায়ী Foo((int&)&&)পতিত হয় Foo(int&)।
আপনার "অনর্থক" ছাড়ের গাইডের ক্ষেত্রে: প্রাথমিকভাবে কোডটির জন্য একটি ডিফল্ট টেম্পলেট ছাড়ের গাইড রয়েছে যা মূলত এর মতো সহায়ক হিসাবে কাজ করে:
template<typename T>
struct Foo {
Foo(T&&) {}
};
template<typename T>
Foo<T> MakeFoo(std::add_rvalue_reference_t<T> value)
{
return Foo<T>(std::move(value));
}
//...
auto f = MakeFoo(x);
এর কারণ এটি স্ট্যান্ডার্ড নির্দেশ করে যে এই (কাল্পনিক) টেমপ্লেট পদ্ধতিতে বর্গ হিসাবে একই টেম্পলেট প্যারামিটার রয়েছে (জাস্ট T) নির্ধারক হিসাবে কোনও টেম্পলেট পরামিতি (এই ক্ষেত্রে কোনওটিই নয়; নির্মাণকারী টেম্পলেট নয়)। তারপরে, ফাংশন প্যারামিটারগুলির ধরণগুলি কনস্ট্রাক্টরের মতো। আমাদের ক্ষেত্রে, তাত্ক্ষণিকতার পরে Foo<int>, নির্মাণকারীর মতো মনে হচ্ছে Foo(int&&), অন্য কথায় একটি মূল্য-রেফারেন্স। সুতরাং add_rvalue_reference_tউপরের ব্যবহার ।
স্পষ্টতই এটি কাজ করে না।
আপনি যখন আপনার "রিডানডান্ট" ছাড়ের গাইড যোগ করবেন:
template<typename T>
Foo(T&&) -> Foo<T>;
আপনি সংযুক্ত রেফারেন্স কোন ধরনের সত্ত্বেও, কম্পাইলার যে পার্থক্য করার অনুমতি দেওয়া Tকন্সট্রাকটর (ইন int&, const int&অথবা int&&ইত্যাদি), আপনি টাইপ বর্গ রেফারেন্স (ঠিক ছাড়া হতে জন্য আমাদের অনুমিত অভিপ্রেত T)। কারণ হঠাৎ আমরা টাইপ অনুমান সম্পাদন করছি ।
এখন আমরা আর একটি (কাল্পনিক) সহায়ক ফাংশন উত্পন্ন করি যা এর মতো দেখায়:
template<class U>
Foo<U> MakeFoo(U&& u)
{
return Foo<U>(std::forward<U>(u));
}
// ...
auto f = MakeFoo(x);
(নির্মাণকারীর কাছে আমাদের কলগুলি ক্লাস টেম্পলেট যুক্তি ছাড়ের উদ্দেশ্যে সহায়িকার ফাংশনে পুনঃনির্দেশিত করা হয়, তাই Foo(x)হয়ে যায় MakeFoo(x))।
এর ফলে U&&পরিণত int&এবং Tকেবল পরিণতint