यहाँ मुद्दा यह है कि, चूंकि वर्ग पर रोक लगाई गई है 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