यह क्यों है कि लैवल्यू और रावल्यू संदर्भ के लिए विशेषज्ञताएं हैं?
अगर केवल प्राथमिक टेम्पलेट से ही अस्तित्व में है, तो कर रही है:
remove_reference<int&>::type
आप दे सकते हैं:
int&
और कर:
remove_reference<int&&>::type
आप दे सकते हैं:
int&&
जो आप नहीं चाहते हैं। लाल्व संदर्भ और रावल्यू संदर्भों के लिए विशेषज्ञता क्रमशः आपके द्वारा पारित तर्क तर्क से &
और &&
को अलग करने की अनुमति देती है।
उदाहरण के लिए, यदि आप कर रहे हैं:
remove_reference<int&&>
प्रकार int&&
T
जा रहा है int
साथ, पैटर्न T&&
विशेषज्ञता द्वारा निर्दिष्ट से मेल खाएगी। के बाद से विशेषज्ञता प्रकार उर्फ type
को परिभाषित करता है T
(इस मामले, int
में) हो सकता है, कर रही है:
remove_reference<int&&>::type
आप int
देंगे।
आप कैसे, हम क्यों move
में remove_reference<t>::type&&
लिए डाली समझा सकता है?
क्योंकि अगर move()
इस प्रकार परिभाषित किया गया है कि:
template<typename T>
T&& move(T&& t) { ... }
// ^^^
// Resolves to X& if T is X& (which is the case if the input has type X
// and is an lvalue)
फिर वापसी प्रकार X&
हो सकता है अगर move()
का तर्क प्रकार X
(कि कैसे तथाकथित "सार्वभौमिक संदर्भ" है की एक lvalue है)। हम यह सुनिश्चित करना चाहते हैं कि वापसी का प्रकार हमेशा एक रावल्यू संदर्भ है।
move()
का उद्देश्य आपको वापस एक rvalue, कोई बात नहीं क्या आप इनपुट में पारित दे रहा है। चूंकि फ़ंक्शन के लिए फ़ंक्शन कॉल होता है जिसके रिटर्न प्रकार एक रावल्यू संदर्भ एक रावल्यू है, हम वास्तव में move()
चाहते हैं कि हमेशा एक रावल्यू संदर्भ लौटाएं। क्योंकि एक गैर संदर्भ प्रकार के &&
जोड़कर हमेशा एक rvalue संदर्भ प्रकार की उपज के लिए गारंटी है
, इसलिए हम remove_reference<T>::type&&
है।
क्या आप यह भी बता सकते हैं कि मैं किस प्रकार से पता लगा सकता हूं और प्रिंट कर सकता हूं?
मुझे यकीन है कि क्या आप "प्रिंट" से यहाँ मतलब यह नहीं कर रहा हूँ। कोई पोर्टेबल तरीका नहीं है जिसे मैं किसी प्रकार के नाम को स्ट्रिंग में परिवर्तित करने के बारे में जानता हूं (इससे कोई फर्क नहीं पड़ता कि आप उस प्रकार को कैसे प्राप्त करते हैं)।
अपने लक्ष्य को यकीन है कि एक rvalue पारित किया गया था बनाने के लिए है, तो दूसरी ओर, आप एक स्थिर दावे तो तरह इस्तेमाल कर सकते हैं:
#include <type_traits>
template<typename T>
void foo(T&&)
{
static_assert(!std::is_reference<T>::value, "Error: lvalue was passed!");
// ...
}
कौन सा तथ्य पर निर्भर करता है कि जब प्रकार X
के lvalue पारित किया जा रहा है, T
X&
होने के लिए घटाया जाएगा।
तुम भी, एक बराबर SFINAE-बाधा इस्तेमाल कर सकते हैं यदि आप केवल एक प्रतिस्थापन विफलता का उत्पादन करना चाहते हैं: आप टेम्पलेट पैरामीटर के रूप में किसी न किसी प्रकार का इलाज जब
#include <type_traits>
template<typename T, typename std::enable_if<
!std::is_reference<T>::value>::type* = nullptr>
void foo(T&&)
{
// ...
}
का उपयोग यह एक ** बहुत ** अच्छा सवाल है! – gedamial