2017-02-13 36 views
6

निम्नलिखित variadic टेम्पलेट को देखते हुए:खाका कटौती

template<typename... Params> 
void fun(void(*f)(Params...), Params... params) { 
    f(params...); 
} 

int main() { 
    fun(+[](int a, int b) {}, 2, 3); 
} 

अब जब एक लैम्ब्डा मैं स्पष्ट रूप से सभी लैम्ब्डा तर्क के प्रकार निर्दिष्ट करने की आवश्यकता के साथ fun लागू के लिए। ऐसा लगता है कि int, int2, 3 से लिया जा सकता है क्योंकि यह अनावश्यक लगता है। क्या इसे अधिक संक्षिप्त और स्वचालित बनाने का कोई तरीका है?

मैं काम करने के लिए निम्न चाहते हैं, लेकिन यह नहीं है:

template<typename... Params> 
void fun(void(*f)(Params...), Params... params) { 
    f(params...); 
} 

int main() { 
    fun(+[](auto a, auto b) {}, 2, 3); 
} 

मैं g++ 5.4.0 और -std=c++14 साथ संकलन कर रहा हूँ।

+1

आपको 'ऑटो' के बजाय 'int' टाइप करने में कोई समस्या है? – Brian

+0

@ ब्रायन हां, cuz यह मुझे यह समझाने की आवश्यकता है कि यह 'int' है। यह और अधिक नाटकीय बनाने के लिए और कुछ भी हो सकता है। –

उत्तर

3

T के बजाय सूचक द्वारा समारोह लें:

template<typename T, typename... Params> 
void fun(T f, Params... params) { 
    f(params...); 
} 

int main() { 
    fun([](auto a, auto b) {}, 2, 3); 
} 

इस तरह से, संकलक चुन सकते हैं जो ओवरलोड कॉल स्थल पर बजाय अगर + ऑपरेटर के अंदर कॉल करने के लिए सही है। जैसा कि टिप्पणी में कहा गया है, वैसे भी + ऑपरेटर जेनेरिक लैम्बडास के लिए परिभाषित नहीं है।


वैकल्पिक रूप से, आप एक पहचान उर्फ ​​का उपयोग करके समारोह सूचक से Params अनुमान करने की कोशिश कर से संकलक निष्क्रिय कर सकते हैं, लेकिन मैं वास्तव में इसे अनुशंसा नहीं करते हैं । वैसे भी, आप यहां जाएं:

template<typename T> 
struct identity { using type = T; }; 

template<typename T> 
using identity_t = typename identity<T>::type; 

template<typename... Params> 
void fun(void(*f)(identity_t<Params>...), Params... params) { 
    f(params...); 
} 

int main() { 
    // v----- no unary +. That operator is not defined for generic lambdas. 
    fun([](auto a, auto b) {}, 2, 3); 
} 
+0

ध्यान दें कि गैर-जेनेरिक लैम्बडास के लिए कोई '+' ऑपरेटर नहीं है। बिल्ट-इन '+' ऑपरेटर का उपयोग किया जाता है, लेकिन लैम्ब्डा इस प्रकार पॉइंटर को फ़ंक्शन पॉइंटर पर अपने रूपांतरण ऑपरेटर का उपयोग करके एक पॉइंटर से जोड़ता है। – Brian

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