यह काम क्यों नहीं करता
मुझे उम्मीद है कि संकलक f()
पुनरावृत्त प्रकार से हल करेगा। जाहिरा तौर पर, यह (gcc 4.1.2) ऐसा नहीं करता है।
अगर ऐसा होता तो बहुत अच्छा होता! हालाँकि, for_each
एक फ़ंक्शन टेम्प्लेट है, जिसे निम्न के रूप में घोषित किया गया है:
template <class InputIterator, class UnaryFunction>
UnaryFunction for_each(InputIterator, InputIterator, UnaryFunction );
टेम्पलेट कटौती UnaryFunction
को कॉल के बिंदु पर एक प्रकार का चयन करने की आवश्यकता है । लेकिन f
एक विशिष्ट प्रकार नहीं है - यह एक अतिभारित कार्य है, f
विभिन्न प्रकारों के साथ प्रत्येक एस है। ऐसा करने के लिए for_each
टेम्पलेट कटौती प्रक्रिया की सहायता के लिए कोई मौजूदा तरीका नहीं f
है, जो यह चाहता है, इसलिए टेम्पलेट कटौती बस विफल हो जाती है। टेम्पलेट कटौती सफल होने के लिए, आपको कॉल साइट पर अधिक काम करने की आवश्यकता है।
इसे ठीक करने के लिए सामान्य समाधान
कुछ वर्षों में यहाँ और बाद में C ++ 14 में होपिंग। उपयोग करने के बजाय एक static_cast
(जो टेम्पलेट कटौती को "फिक्सिंग" द्वारा सफल होने की अनुमति देगा, जिसे f
हम उपयोग करना चाहते हैं, लेकिन आपको मैन्युअल रूप से "एक" को "ठीक" करने के लिए अधिभार संकल्प करने की आवश्यकता है, हम हमारे लिए संकलक का काम करना चाहते हैं। हम f
कुछ आर्गन्स पर कॉल करना चाहते हैं । सबसे सामान्य तरीके से संभव है, कि:
[&](auto&&... args) -> decltype(auto) { return f(std::forward<decltype(args)>(args)...); }
यह टाइप करने के लिए बहुत कुछ है, लेकिन इस तरह की समस्या अक्सर परेशान होती है, इसलिए हम इसे एक मैक्रो (आह) में लपेट सकते हैं:
#define AS_LAMBDA(func) [&](auto&&... args) -> decltype(func(std::forward<decltype(args)>(args)...)) { return func(std::forward<decltype(args)>(args)...); }
और फिर इसका उपयोग करें:
void scan(const std::string& s) {
std::for_each(s.begin(), s.end(), AS_LAMBDA(f));
}
यह वही करेगा जो आप चाहते हैं कि संकलक ने किया - नाम पर f
ही अधिभार संकल्प निष्पादित करें और बस सही काम करें। यह f
निशुल्क कार्य या सदस्य कार्य की परवाह किए बिना काम करेगा ।