2011-07-06 8 views
10

मैं लिए अक्सर पूछे जाने How do I specify a pointer to an overloaded function? जवाब पता: या तो काम के साथ या एक कलाकारों के साथ, और हर दूसरे सी ++ ट्यूटोरियल इस तरह एक स्ट्रिंग (दे या ले static_cast) uppercases:मैं एल्गोरिदम में डिफ़ॉल्ट तर्कों के साथ अधिभारित फ़ंक्शंस का उपयोग कैसे करूं?

transform(in.begin(), in.end(), back_inserter(out), (int(*)(int)) std::toupper); 

या इस तरह :

int (*fp)(int) = std::toupper; 
transform(in.begin(), in.end(), back_inserter(out), fp); 

कौन सा बड़े करीने से std::toupper की <cctype> अधिभार चयन करता है।

लेकिन इस सवाल भीख माँगता: मैं कैसे एक समान तरीके से <locale> अधिभार का चयन कर सकते हैं?

char (*fp2)(char, const std::locale&) = std::toupper; 
transform(in.begin(), in.end(), back_inserter(out), fp2); 
// error: too few arguments to function 

या, अधिक व्यावहारिक रूप से, किसी एक एल्गोरिथ्म में सी ++ 11 std::stoi उपयोग करने के लिए पूर्णांकों का एक वेक्टर के लिए तार का एक वेक्टर परिवर्तित करने के लिए कोशिश कर रहा पर विचार करें: stoi दो भार के (string/wstring) है, इसलिए प्रत्येक लेने दो अतिरिक्त डिफ़ॉल्ट तर्क।

मान लीजिए कि मैं उन सभी डिफ़ॉल्टों को explicitly bind नहीं करना चाहता, मुझे विश्वास है कि इस तरह के कॉल को सहायक फ़ंक्शन या लैम्ब्डा में लपेटने के बिना ऐसा करना असंभव है। क्या मेरे लिए पूरी तरह से सामान्य तरीके से ऐसा करने के लिए कोई बूस्ट रैपर या टीएमपी जादू है? एक रैपर call_as<char(char)>(fp2) या अधिक संभावना है, call_as<int(const std::string&)>(std::stoi) भी लिखा जा सकता है?

+3

आप बस अपने 'transform' आदेश में एक लैम्ब्डा का उपयोग कर सकते हैं? सबसे आसान और साफ। –

+0

मैंने पहले से ही जिस रैपर को खोज रहे थे, उसके बारे में 'बाइंड' के बारे में एक टिप्पणी लिखी और हटा दी। तब यह मेरे लिए हुआ कि आपको बाध्य करने के लिए डिफ़ॉल्ट मान प्रदान करना होगा, इस प्रकार उन्हें फिर से परिभाषित करना होगा। –

+0

टेम्पलेट सामग्री के माध्यम से कोड को कैसे रोकना है, इस बारे में सोचने से पहले एल्गोरिदम सही होना बेहतर है। तो, एल्गोरिदम के साथ शुरू करें। 'std :: toupper' कॉल 'EOF' मान को छोड़कर नकारात्मक तर्क होने पर अपरिभाषित व्यवहार उत्पन्न करता है। –

उत्तर

5

यह अजीब है, मैं कुछ इसी तरह कर रहा था। ऐसा करने का सबसे अच्छा तरीका यह है कि यह लैम्ब्डा का उपयोग निम्न प्रकार से कर रहा था, क्योंकि अन्यथा, आपको सही अधिभार प्राप्त करने के लिए टाइपिफ़ का उपयोग करना होगा और लोकल से छुटकारा पाने के लिए std :: bind का उपयोग करना होगा, या लोकेल का उपयोग नहीं करना चाहिए। हालांकि, यह अधिक स्वच्छता से काम करता है:

static const std::locale loc; 
transform(in.begin(), in.end(), back_inserter(out), [&loc](char c) { 
    return std::toupper(c, loc); 
}); 

मैं प्रत्येक बार फिर से आवंटित करने के प्रयास को बचाने के लिए स्थिर का उपयोग करता हूं।

या आप एक typedef मिल सकता है और कार्य करें:

std::bind((LocaleCompare)std::toupper, std::placeholders::_1, loc); // UGLY! 
0

आपको लगता है कि functon सूचक प्रकार का एक typedef बनाना चाहिए सकता है, और फिर समारोह डाली।

typedef char (*LocaleToUpper)(char, const std::locale&) ; 
char (*fp2)(char, const std::locale&) = (LocaleToUpper)toupper; 
संबंधित मुद्दे