मिनट एल्गोरिथ्म सामान्य रूप से इस तरह व्यक्त किया जाता है:मिनट और सही अग्रेषण
template <typename T>
const T& min(const T& x, const T& y)
{
return y < x ? y : x;
}
हालांकि, इस प्रपत्र min(a, b) = 0
के निर्माणों की अनुमति नहीं है।
template <typename T>
T& min(T& x, T& y)
{
return y < x ? y : x;
}
मैं करना चाहते हैं क्या सही अग्रेषण के माध्यम से इन दो भार के एकजुट है:: आप एक अतिरिक्त अधिभार के साथ कि प्राप्त कर सकते हैं
template <typename T>
T&& min(T&& x, T&& y)
{
return y < x ? std::forward<T>(y) : std::forward<T>(x);
}
हालांकि, जी ++ 4.5.0 min(2, 4)
के लिए एक चेतावनी बाहर थूक कि मैं एक अस्थायी के लिए एक संदर्भ वापस। क्या मैंने कुछ गलत किया?
ठीक है, मुझे मिल गया। समस्या सशर्त ऑपरेटर के साथ है। मेरे पहले समाधान में, यदि मैं min(2, 4)
पर कॉल करता हूं तो सशर्त ऑपरेटर एक xvalue देखता है और इस प्रकार एक अस्थायी वस्तु उत्पन्न करने के लिए अग्रेषित x
से आगे बढ़ता है। बेशक यह संदर्भ के द्वारा वापस करने के लिए खतरनाक होगा! मैं x
और y
अलग से करने के बजाय पूरे अभिव्यक्ति अग्रेषित करते हैं, संकलक अब शिकायत नहीं करता है:
template <typename T>
T&& min(T&& x, T&& y)
{
return std::forward<T>(y < x ? y : x);
}
ठीक है, मैं अंकगणित प्रकार :)
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type
min(T x, T y)
{
return y < x ? y : x;
}
template <typename T>
typename std::enable_if<!std::is_arithmetic<T>::value, T&&>::type
min(T&& x, T&& y)
{
return std::forward<T>(y < x ? y : x);
}
हम्म यह मुझे लगता है कि आखिरी उदाहरण एफसीडी के अनुसार भी एक अस्थायी बनाता है। लेकिन यह अजीब लगता है: ऐसा लगता है कि 'int &&' को 'int' xvalue पर बाध्य करने के लिए अस्थायी बनाना है ?! मैंने सोचा कि xvalues अज्ञात रावल्यू रेफ हैं जो अस्थायी संदर्भों के बिना रैल्यू संदर्भों से बंधे जा सकते हैं? ऐसा लगता है कि आपके संशोधित कोड के लिए ऐसा नहीं है, है ना? वापसी प्रकार 'int &&' है, और वापसी अभिव्यक्ति एक 'int' xvalue है। संकलक अब इसके लिए चेतावनी क्यों नहीं देता है? –
यदि मैं सही तरीके से '8.5.3' पढ़ता हूं, तो यह कहता है कि यह xvalue के संदर्भ को बाध्य करते समय एक अस्थायी बनाता है:' int x = 0; int && rx = (int &&)x; 'इसी तरह 'std :: move' का उपयोग करते समय। यह इरादा नहीं हो सकता है, मुझे लगता है। –
@ जोहान्स: 8.5.3 का कौन सा हिस्सा आप विशेष रूप से बात कर रहे हैं? – fredoverflow