2013-05-11 8 views
8

एक सामान्य न्यूनतम कार्य लिखना, मेरे दिमाग में दो प्रश्न आए। कोड किसी भी इनपुट प्रकार और विभिन्न तर्क संख्या के साथ ठीक काम करता है:सामान्य न्यूनतम और अधिकतम - सी ++

namespace xyz 
{ 

template <typename T1, typename T2> 
auto min(const T1 &a, const T2 &b) -> decltype(a+b) 
{ 
    return a < b ? a : b; 
} 

template <typename T1, typename T2, typename ... Args> 
auto min(const T1 &a, const T2 &b, Args ... args) -> decltype(a+b) 
{ 
    return min(min(a, b), args...); 
} 

} 

int main() 
{ 
    cout << xyz::min(4, 5.8f, 3, 1.8, 3, 1.1, 9) << endl; 
    //     ^ ^  ^
    //     |  |   | 
    //     float double  int 
} 

 

  • वहाँ decltype(a+b) के लिए एक बेहतर प्रतिस्थापन है? मुझे लगता है कि एक मानक वर्ग है जिसे मैं याद नहीं कर सकता, decltype(std::THE_RESULT<a,b>::type) जैसे कुछ।

  • decltype(std::THE_RESULT<a,b>::type) का लौटा प्रकार const & है या नहीं?

+1

यह मेरे लिए अजीब लगता है कि आप एक और ख विभिन्न प्रकार होने के लिए अनुमति देते हैं। यह सभी प्रकार के गैरकानूनी तुलनाओं के लिए दरवाजा खुलता है, जैसे 'मिनट (42," तीन ")'। क्यों दोनों पैरामीटर (और वापसी मूल्य) की आवश्यकता नहीं है सभी एक ही प्रकार के हो? –

+1

@AdrianMcCarthy: _ "अंकगणितीय प्रकारों के लिए, सामान्य प्रकार को (संभवतः मिश्रित-मोड) अंकगणितीय अभिव्यक्ति के प्रकार के रूप में देखा जा सकता है जैसे कि टी 0() + टी 1() + ... + टीएन()" _। तो मुझे लगता है, यह 'मिनट (42," तीन ")' उपयोग करने के लिए निषिद्ध है। यह संकलन त्रुटि बनाता है। – deepmax

+0

वैसे, टेम्पलेट का उपयोग कर मैक्रो संस्करणों के अच्छे हिस्सों को पुन: पेश करने पर एक लेख है। यह आश्चर्यजनक रूप से करने के लिए बहुत कुछ है। – chris

उत्तर

13

std::common_type (c++11):

गैर विशेष std::common_type, प्रत्येक जोड़ी के T1 के बीच आम प्रकार का निर्धारण करने के लिए नियमों के लिए, T2 की वापसी प्रकार का निर्धारण करने के लिए वास्तव में नियम हैं टर्नरी सशर्त ऑपरेटर जहां T1 और T2 इसके दूसरे और तीसरे ऑपरेटरों के प्रकार हैं।

और

अंकगणित प्रकार के लिए, आम प्रकार भी प्रकार (संभवतः मिश्रित मोड) के अंकगणितीय अभिव्यक्ति जैसे T0() + T1() + ... + Tn().

के बारे में सुनिश्चित नहीं हैं कि के रूप में देखा जा सकता है const&, लेकिन आप उत्तर जानने के लिए std::remove_cv और std::remove_reference (और std::is_reference के साथ खेल सकते हैं)।

वास्तव में, here's प्रकार की समर्थन उपयोगिताओं की एक सूची। अपने आप को बाहर करना।

+0

को संभालने के लिए प्रोग्रामर पर है धन्यवाद ... मैंने एक तीसरा संबंधित प्रश्न जोड़ा। क्या आप इसे देखने पर ध्यान देंगे? – deepmax

+2

@ एमएम।यह काम करेगा लेकिन पूरी तरह से नहीं है जो आप चाहते हैं। '(1,2,1.1)' के लिए जो 'int' वापस कर देगा। 'decltype (न्यूनतम (1, 2))'। आप पूरी तरह से 'decltype (min (min (a, b), args ...)) को कवर करने का प्रयास कर सकते हैं) लेकिन यह अभी' gcc' के साथ काम नहीं करता है। मुझे लगता है कि यह एक बग है। – stardust

+0

@ नामांकित: हाँ, मैंने इसका परीक्षण किया और आप सही हैं। – deepmax

5

जवाब और लायक टिप्पणियां मैं इसे नीचे के रूप में किया था के बाद:

template <typename T1, typename T2> 
auto min(const T1 &a, const T2 &b) 
-> typename std::common_type<const T1&, const T2&>::type 
{ 
    return a < b ? a : b; 
} 

template <typename T1, typename T2, typename ... Args> 
auto min(const T1 &a, const T2 &b, const Args& ... args) 
-> typename std::common_type<const T1&, const T2&, const Args& ...>::type 
{ 
    return min(min(a, b), args...); 
} 
संबंधित मुद्दे