2012-08-17 12 views
15

मैं एक टेम्पलेट फ़ंक्शन लिखना चाहता हूं जो 2 मानों और एक मज़ेदार या लैम्ब्डा स्वीकार करता है। फ़ंक्शन मल्टीक्टर को उन मानों के साथ कॉल करता है और परिणाम देता है।फ़ैक्टर के वापसी मूल्य के प्रकार को कैसे घटाया जाए?

template <typename T, typename Fn> 
_ReturnTypeOfPred_ Apply(T x, T y, Fn fn) 
    { 
    return fn(x, y); 
    } 

प्रश्न: मैं Apply की वापसी प्रकार परिभाषित कर सकते कैसे Fn की वापसी प्रकार के बराबर हो जाते हैं? यह functor

template <typename T> 
auto Sum(T x, T y) -> decltype(x+y) 
    { 
    return x+y; 
    } 

अद्यतन

1 उदाहरण oversimplified था की इस उदाहरण में जरूरी T के बराबर नहीं है,। क्या यह काम करेगा?

template <typename TContainer, typename Fn> 
auto Apply(const TContainer& x, const TContainer& y, Fn fn) -> decltype(fn(x.front(), y.front())) 
    { 
    return fn(x.front(), y.front()); 
    } 

यह हमेशा अगर मैं वापसी प्रकार की decltype में return अभिव्यक्ति दोहराने काम करोगे? क्या कोई और सुरुचिपूर्ण तरीका है?

+2

अंडरस्कोर-पूंजी नाम कार्यान्वयन के लिए आरक्षित हैं। आपको उन्हें अपने कोड में उपयोग नहीं करना चाहिए। –

+2

@KerrekSB: यह प्लेसहोल्डर था, वास्तविक कोड नहीं – Andrey

+0

अच्छे मल्टीक्टर (जैसे कि एसटीएल में) हमेशा अपने 'वापसी_ प्रकार' को परिभाषित करते हैं, ताकि आप केवल 'Fn :: return_type' का उपयोग कर सकें। लेकिन मैं समझता हूं कि आप एक ऐसा उत्तर चाहते हैं जो बहुत अच्छे मज़दूरों के लिए भी काम न करे। – Gorpik

उत्तर

18

आप लगभग वहां हैं; बस decltype का उपयोग करें:

template <typename T, typename Fn> 
auto Apply(T x, T y, Fn fn) -> decltype(fn(x, y)) 
{ 
    return fn(x, y); 
} 

आप std::result_of (Difference between std::result_of and decltype) लेकिन क्यों परेशान इस्तेमाल कर सकते हैं?

template <typename T, typename Fn> 
typename std::result_of<Fn, T, T>::type Apply(T x, T y, Fn fn) 
{ 
    return fn(x, y); 
} 

अनुवर्ती प्रश्न के बारे में: एक समारोह

auto fn(<args>) -> <return-type> { return <expression>; } 

decltype(<expression>) होगा आमतौर पर काम के साथ return-type प्रतिस्थापन के लिए है, लेकिन त्रुटियों की संभावना हो सकती है। उदाहरण के लिए, पर विचार करें:

auto f(char c) -> decltype(std::string() += c) { return std::string() += c; } 

यहाँ decltypestd::string & निकलेगा और अपने समारोह एक स्थानीय के लिए एक lvalue संदर्भ वापस आ जाएगी! कि जैसे होने के कारण के लिए वापस नहीं है एक मूल्य उत्पन्न हो सकते हैं

auto f(char c) -> std::remove_reference<decltype(std::string() += c)>::type { 
    return std::string() += c; 
} 

अन्य मामलों में, <expression>: यह करने के लिए बदल करना होगा noncopyable, एक लैम्ब्डा, आदि

+0

धन्यवाद, क्या आप अपडेट किए गए प्रश्न पर एक नज़र डाल सकते हैं? – Andrey

+0

@Andrey ऊपर देखें। – ecatmur

+0

आपके द्वारा लिंक किया गया प्रश्न 'std :: result_of' और 'decltype' के बीच अंतर को वास्तव में अच्छी तरह से रेखांकित नहीं करता है। ओपी के प्रयोजनों के लिए, 'std :: result_of' उचित नहीं है। –

संबंधित मुद्दे