2011-11-22 16 views
5

मैं नए C++ मानक में variadic टेम्पलेट्स के साथ चारों ओर खेल रहे हैं और एक नक्शे के समारोह के साथ आया था (हेडर बाहर रखा गया decs का उपयोग कर +):C++ समारोह नक्शा कार्यान्वयन

template<typename T> 
T square(T i) 
{ 
     return i * i; 
} 

template <typename T, typename... Ts> 
const tuple<Ts...> map(const T f, const Ts...args) 
{ 
     return make_tuple(f(args)...); 
} 

int main(int c, char *argv[]) 
{ 
     tuple<int, int> t; 
     int (*fp) (int) = square; 

     t = map(fp, 6, 8); 

     cout <<get<0>(t) <<endl; 
     cout <<get<1>(t) <<endl; 

     return 0; 
} 

कौन सा काम करता है। जब तक सभी तर्क नक्शे के लिए एक ही प्रकार के होते हैं।

tuple<int, float> t; 

t = map(square, 6, 8.0f); 

जीसीसी 4.4 रिपोर्ट:: मैं मुख्य एक से थोड़ा अधिक सामान्य रूप का उपयोग करने को बदलते हैं

In function ‘int main(int, char**)’: 
error: no matching function for call to ‘map(<unresolved overloaded function type>, int, float)’ 

कोई भी विचार कैसे इस काम करने के लिए?

+3

क्या आप नेमस्पेस std का दुरुपयोग कर रहे हैं; '? 'Tuple' कहां से आता है? –

+0

@ केरेकस्क: वह कहता है कि उसने 'डीक का उपयोग करके' हटा दिया, जो मुझे 'दुर्व्यवहार का उपयोग करके स्पष्ट' लगता है। –

उत्तर

5

सबसे पहले, आप एक पॉइंटर (या टेम्पलेट पैरामीटर) के रूप में एक अनसुलझा फ़ंक्शन टेम्पलेट को पास नहीं कर सकते हैं, आप केवल इसके उदाहरणों को पार कर सकते हैं। इसका अर्थ यह है कि इस उदाहरण में आपके टेम्पलेट का पहला तर्क int (*)(int) के रूप में पारित किया जा रहा है, और float (*)(float) तत्कालता को कॉल नहीं कर सकता है। मुझे यह तय करने का सबसे अच्छा तरीका नहीं है, लेकिन वैसे भी यह तकनीकी रूप से नहीं है जिसे आपने पूछा था।

मेरे पास इसका परीक्षण करने के लिए एक कंपाइलर नहीं है, लेकिन मुझे लगता है कि अगर आप std::function का उपयोग उन प्रकारों को अनुमानित करने के लिए करते हैं, जिन्हें आप चाहते हैं कि फ़ंक्शन आप चाहते हैं, तो आप पैरामीटर को फ़ंक्शन में डालने में सक्षम हो सकते हैं। इस तरह:

template<typename T, typename Ts...> 
tuple<Ts...> map(std::function<T (T)> const &f, Ts... args) { 
    return make_tuple(static_cast<Ts>(f(static_cast<T>(args)))...); 
} 

देखें, मैं तुम्हें समारोह के लिए कास्ट करने के लिए दोनों (एक T के रूप में) पैरामीटर और (एक Ts के रूप में) वापसी प्रकार की जरूरत है, क्योंकि यह कुछ निहित रूपांतरण नियम इस के अंदर काम नहीं कर रहे लगती है टेम्पलेट।

यदि मेरा वाक्यविन्यास काम नहीं करता है (शायद यह नहीं है, ... एस आपके लिए एक कंपाइलर नहीं है तो मुश्किल हो सकता है), यह संभव है कि आप इसे अधिक वर्बोज़ फ़ंक्शन के रूप में पुनः लिख सकें जो फ़ंक्शन को कॉल करने से पहले प्रत्येक Ts को अनपैक करता है, और उसके बाद एक टुपल बनाता है। मुझे यकीन नहीं है कि यह वास्तव में जरूरी है, लेकिन मेरी भावना यह है कि ... अनपॅकिंग के लिए कंपाइलर समर्थन अभी थोड़ा सा स्पॉटी है, इसलिए यदि आप काम करने वाले किसी चीज़ के साथ आते हैं, तो मुझे आश्चर्य नहीं होगा आपका कंपाइलर इसे संभाल नहीं सका।

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