के अस्तित्व के कारण क्या हैं std::decay
? किन स्थितियों में std::decay
उपयोगी है?
decay_t<decltype(...)>
एक अच्छा संयोजन है, यह देखने के लिए कि क्या कम auto
होगा।
के अस्तित्व के कारण क्या हैं std::decay
? किन स्थितियों में std::decay
उपयोगी है?
decay_t<decltype(...)>
एक अच्छा संयोजन है, यह देखने के लिए कि क्या कम auto
होगा।
जवाबों:
<मजाक> यह स्पष्ट रूप से std::atomic
गैर-रेडियोधर्मी लोगों में रेडियोधर्मी प्रकारों को क्षय करने के लिए उपयोग किया जाता है। </ मजाक>
N2609 वह कागज है जो प्रस्तावित था std::decay
। कागज बताते हैं:
सीधे शब्दों में कहें,
decay<T>::type
तो पहचान प्रकार-परिवर्तन है, सिवाय अगर टी एक सरणी प्रकार या फ़ंक्शन प्रकार का संदर्भ है। उन मामलों मेंdecay<T>::type
क्रमशः एक कार्य करने के लिए एक सूचक या एक सूचक देता है।
प्रेरक उदाहरण C ++ 03 है std::make_pair
:
template <class T1, class T2>
inline pair<T1,T2> make_pair(T1 x, T2 y)
{
return pair<T1,T2>(x, y);
}
जो स्ट्रिंग मापदंडों को काम करने के लिए इसके मापदंडों को स्वीकार करते हैं:
std::pair<std::string, int> p = make_pair("foo", 0);
यदि यह संदर्भ द्वारा अपने मापदंडों को स्वीकार करता है, तो T1
एक सरणी प्रकार के रूप में कटौती की जाएगी, और फिर एक निर्माण का निर्माण pair<T1, T2>
बीमार होगा।
लेकिन स्पष्ट रूप से यह महत्वपूर्ण अक्षमताओं की ओर जाता है। इसलिए decay
, पास-दर-मूल्य होने पर होने वाले परिवर्तनों के सेट को लागू करने की आवश्यकता होती है, जिससे आप संदर्भ द्वारा मापदंडों को लेने की दक्षता प्राप्त कर सकते हैं, लेकिन फिर भी आपके कोड को स्ट्रिंग शाब्दिकों के साथ काम करने के लिए आवश्यक प्रकार के परिवर्तन मिलते हैं, सरणी प्रकार, फ़ंक्शन प्रकार और जैसे:
template <class T1, class T2>
inline pair< typename decay<T1>::type, typename decay<T2>::type >
make_pair(T1&& x, T2&& y)
{
return pair< typename decay<T1>::type,
typename decay<T2>::type >(std::forward<T1>(x),
std::forward<T2>(y));
}
नोट: यह वास्तविक C ++ 11 make_pair
कार्यान्वयन नहीं है - C ++ 11 make_pair
भी अलिखित है std::reference_wrapper
।
टेम्पलेट प्रकार के मापदंडों को लेने वाले टेम्पलेट फ़ंक्शंस से निपटने के दौरान, आपके पास अक्सर सार्वभौमिक पैरामीटर होते हैं। सार्वभौमिक पैरामीटर लगभग हमेशा एक प्रकार या किसी अन्य के संदर्भ होते हैं। वे कांस्टेबल-वाष्पशील भी हैं। जैसे कि, अधिकांश प्रकार के लक्षण उन पर काम नहीं करते हैं जैसा कि आप अपेक्षा करते हैं:
template<class T>
void func(T&& param) {
if (std::is_same<T,int>::value)
std::cout << "param is an int\n";
else
std::cout << "param is not an int\n";
}
int main() {
int three = 3;
func(three); //prints "param is not an int"!!!!
}
http://coliru.stacked-crooked.com/a/24476e60bd906bed
यहाँ समाधान का उपयोग करना है std::decay
:
template<class T>
void func(T&& param) {
if (std::is_same<typename std::decay<T>::type,int>::value)
std::cout << "param is an int\n";
else
std::cout << "param is not an int\n";
}
decay
बहुत आक्रामक है, उदाहरण के लिए अगर यह एक पॉइंटर की पैदावार के संदर्भ में लागू होता है। यह आमतौर पर इस तरह के मेटाप्रोग्रामिंग IMHO के लिए बहुत आक्रामक है।
remove_const_t< remove_reference_t<T> >
, संभवत: एक कस्टम परिवर्तन में लिपटे हुए हूं।