2011-11-28 4 views
5

मान लीजिए अगर मैं इस किया है,std :: function <R(T1,T2)> के साथ संगत फ़ंक्शन प्रकार के सेट को निर्धारित करने के नियम?

std::function<int(int,int)> fs; 

तो मैं कैसे काम करता है (या समारोह वस्तुओं) जो fs साथ प्रारंभ किया जा सकता है के सेट निर्धारित कर सकते हैं?

कौन सा folllowing की अनुमति दी है और नहीं जो:

std::function<int(int,int)> fs = [](int, int) { return int(10); }; 
std::function<int(int,int)> fs = [](char, char) { return char(10); }; 
std::function<int(int,int)> fs = [](int, short) { return int(10); }; 
std::function<int(int,int)> fs = [](double, int) { return float(10); }; 
std::function<int(int,int)> fs = [](int, wchar_t) { return wchar_t(10); }; 

std::function<int(int,int)> fs = [](const char*, int){ return "string"; }; 
std::function<int(int,int)> fs = [](const char*, int){ return 10; }; 
std::function<int(int,int)> fs = [](const char*, int){ return std::string(); }; 
बेशक

, मैं संकलन और देखो, जो एक ठीक संकलित कर सकते हैं और जो नहीं करता है। लेकिन यह मुझे पैरामीटर के प्रकार और रिटर्न प्रकार में बदलावों को समझने में मदद नहीं करता है। उनके लिए विभिन्न प्रकारों का उपयोग करने के लिए मैं कितनी दूर जा सकता हूं?

इसे दूसरे शब्दों में रखने के लिए, अगर मैंने कोई फ़ंक्शन (या फ़ंक्शन ऑब्जेक्ट) दिया है, तो मैं संकलन-समय पर कैसे निर्धारित कर सकता हूं यदि यह std::function<int(int,int)> के साथ संगत है या नहीं? मुझे थोड़ा समझ है, लेकिन मुझे पर्याप्त विश्वास नहीं है।

तो कृपया std::function<R(T1,T2)> के साथ संगत फ़ंक्शन प्रकार के सेट को निर्धारित करने के लिए नियमों को समझने और निकालने में मेरी सहायता करें? क्या मेटाप्रोग्रामिंग उपयोगकर्ताओं को सूचित करने के लिए यहां मेरी सहायता कर सकती है, अगर वे असंगत फ़ंक्शन का उपयोग करते हैं, तो अच्छा त्रुटि संदेश उत्पन्न करते हैं? , http://ideone.com/hJpG3

उत्तर

4

वस्तु (समारोह सूचक या functor) दिया गया आर्ग्यूमेंट प्रकार के साथ प्रतिदेय होना चाहिए अर्थात fun(declval<Types>() ...) अच्छी तरह से गठित और परोक्ष R के लिए परिवर्तनीय है:

वैसे, पहले समूह संगत हो रहा है।

विशेष रूप से सी ++ 11 §20.8.2 देखें; यह पॉइंटर्स-टू-सदस्यों आदि के लिए विभिन्न विशेष मामले देता है। §20.8.11.2/2 और 20.8.11.2.1/7 इसे std::function कन्स्ट्रक्टर से जोड़ दें।

4

कोई प्री-पैक किया गया मेटाप्रोग्रामिंग समाधान नहीं है। मैंने इस प्रश्न के साथ मदद करने के लिए निम्नलिखित लक्षणों को प्रोग्राम किया है। ये लक्षण केवल पोटाटोस्वाटर के जवाब में निर्दिष्ट खंडों को लागू करते हैं। कोड टिप्पणियां संदर्भित अनुभागों में बुलेट बिंदुओं को भी गिनती करती हैं।

template <class _F, class ..._Args> struct __invokable; 
template <class _F, class ..._Args> struct __invoke_of; 

http://llvm.org/svn/llvm-project/libcxx/trunk/include/type_traits

मैं इन का उपयोग किया है std::function के एक निजी "सदस्य विशेषता" बनाने के लिए:

template <class _F, bool = __invokable<_F&, _ArgTypes...>::value> 
    struct __callable; 

http://llvm.org/svn/llvm-project/libcxx/trunk/include/functional

यह मेरे लिए हुआ है कि इन अच्छा कर सकता है tr2 सामग्री (अग्रणी अंडरस्कोर sans)। यदि आप सहमत हैं, तो शायद आपको अपने राष्ट्रीय शरीर के प्रतिनिधि को जानना चाहिए।

यदि आप इन लक्षणों का उपयोग करना चाहते हैं, तो कोड खुला स्रोत है। लेकिन यदि आप प्रत्येक फ़ाइल में कॉपीराइट जानकारी सहित ओपन सोर्स लाइसेंस का सम्मान करते हैं तो मैं इसकी सराहना करता हूं।

+0

ऐसा लगता है कि यह उत्तर मानक लाइब्रेरी द्वारा प्रकट कार्यक्षमता के संदर्भ में है ... यदि मेरा उत्तर गलत है, तो क्या आप टिप्पणी कर सकते हैं? संपादित करें - यह विशेषता वापसी मान रूपांतरण को अनदेखा कर रही है ... – Potatoswatter

+0

@Potatoswatter: मैंने अभी इन लक्षणों के कार्यान्वयन की समीक्षा की है। वे 'std :: forward',' std :: is_convertible' और 'std :: is_same' पर निर्भर करते हैं। उन्हें std :: lib या नहीं के हिस्से के रूप में कार्यान्वित किया जा सकता है।मैंने अपने जवाब की भी समीक्षा की है और यह नहीं देख रहा हूं कि मैंने कहां बताया कि आपका जवाब गलत है। मेरा जवाब बस आपके द्वारा संदर्भित अनुभागों का मेटाप्रोग्रामिंग कार्यान्वयन प्रदान करता है। ओपी ने मेटाप्रोग्रामिंग समाधान के बारे में पूछा, इसलिए मैंने सोचा कि मेरा जवाब प्रासंगिक है। रिटर्न वैल्यू रूपांतरण पर: यह '__invoke_of' और' is_convertible' का उपयोग कर '__callable' में शामिल है। –

+1

ठीक है। एकमात्र असहमति यह होगी कि मैं अपनी प्रतिक्रिया को "पूर्व-पैक मानक जवाब" मानता हूं। रिटर्न प्रकार रूपांतरण के लिए, मैंने लिंक का पालन नहीं किया और माना कि यह एक गैर-सदस्य टेम्पलेट था, वांछित रिटर्न प्रकार तक पहुंच नहीं थी। उपयोगकर्ता स्तर पर, 'std :: is_convertible :: प्रकार, R> :: value' पर्याप्त नहीं है? मुझे लगता है कि यह निर्भर करता है कि आप SFINAE या 'false' परिणाम चाहते हैं। – Potatoswatter

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