कई boost::fusion::fold
ओवरलोड हैं। boost's svn repo से:
template<typename Seq, typename State, typename F>
inline typename result_of::BOOST_FUSION_FOLD_NAME<
Seq const
, State const
, F
>::type
BOOST_FUSION_FOLD_NAME(Seq const& seq, State const& state, F f)
{
return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State const,F>::call(
state,
seq,
f);
}
template<typename Seq, typename State, typename F>
inline typename result_of::BOOST_FUSION_FOLD_NAME<
Seq
, State const
, F
>::type
BOOST_FUSION_FOLD_NAME(Seq& seq, State& state, F f)
{
return result_of::BOOST_FUSION_FOLD_NAME<Seq,State,F>::call(
state,
seq,
f);
}
template<typename Seq, typename State, typename F>
inline typename result_of::BOOST_FUSION_FOLD_NAME<
Seq const
, State const
, F
>::type
BOOST_FUSION_FOLD_NAME(Seq const& seq, State& state, F f)
{
return result_of::BOOST_FUSION_FOLD_NAME<Seq const,State,F>::call(
state,
seq,
f);
}
संकलक एक बार प्रकार कटौती और प्रतिस्थापन सफल रहा है इन सभी वेरिएंट के लिए वर्ग टेम्पलेट result_of::BOOST_FUSION_FOLD_NAME
(*) वापसी प्रकार में दृष्टांत के लिए, से पहले एक अधिभार चयन किया जाता है की अनुमति है। इस मामले में, यह निर्धारित करने के लिए कि रिटर्न प्रकार मान्य है या नहीं, संकलक को इस क्लास टेम्पलेट को तुरंत चालू करना होगा। यदि रिटर्न प्रकार में प्रतिस्थापन (टेम्पलेट तर्कों का) एक अमान्य प्रकार तत्काल संदर्भ में जाता है, तो ओवरलोड को त्याग दिया जाता है। इसे SFINAE के रूप में जाना जाता है।
(*) यह नाम आम तौर पर result_of::fold
पर हल करता है।
Seq const&
पैरामीटर वाले ओवरलोड में से एक का तत्कालता लैम्बडा के रिटर्न प्रकार को निर्धारित करने के लिए अब कोशिश करता है। हालांकि, के साथ लैम्ब्डा को तुरंत चालू करना दूसरा तर्क विफल रहता है: increment
किसी कॉन्स्ट ऑब्जेक्ट पर नहीं कहा जा सकता है (यह संकलक आपको बताता है)।
यदि रिटर्न प्रकार का निर्धारण विफल रहता है, तो fold
ओवरलोड में प्रतिस्थापन विफलता होनी चाहिए, हम वापसी प्रकार निर्धारित करने का प्रयास कर रहे हैं। हालांकि, लैम्बडास में स्वचालित रिटर्न प्रकार कटौती के कारण प्रतिस्थापन विफलता और सी ++ 14 फ़ंक्शंस मूल टेम्पलेट fold
के तत्काल संदर्भ में नहीं हैं: के भीतर होता है जो स्वचालित रिटर्न प्रकार कटौती (यहां: लैम्ब्डा) का उपयोग करने वाले फ़ंक्शन का होता है।
मूल प्रतिस्थापन के तत्काल संदर्भ में एक प्रतिस्थापन विफलता नहीं है एक कठिन त्रुटि है, यह एक SFINAE-प्रकार त्रुटि नहीं है जिसे आप पुनर्प्राप्त कर सकते हैं। (SFINAE = SFIICINAE)
यदि आप स्पष्ट रूप से लैम्ब्डा, [](int i, auto& x) -> int {return x.increment(i);}
के रिटर्न प्रकार को निर्दिष्ट करते हैं, तो फ़ंक्शन/लैम्ब्डा को रिटर्न प्रकार निर्धारित करने के लिए तत्काल आवश्यकता नहीं है। इसे अकेले घोषणा से निर्धारित किया जा सकता है। इसलिए, किसी भी ओवरलोड के लिए रिटर्न प्रकार के आधार पर कोई प्रतिस्थापन विफलता नहीं होती है, और सामान्य ओवरलोड रिज़ॉल्यूशन उचित अधिभार का चयन कर सकता है। गैर-कॉन्स Seq&
अधिभार चुना जाता है, और लैम्ब्डा का त्वरण मान्य होगा।
इसी प्रकार, स्पष्ट रूप से लिखित मज़ेदार के लिए: यदि रिटर्न प्रकार को फ़ंक्शन को तत्काल किए बिना निर्धारित किया जा सकता है, तो कोई त्रुटि नहीं होगी।आप साधारण कार्यों के लिए सी ++ 14 की वापसी प्रकार कटौती का उपयोग करते हैं, एक ही समस्या होती है:
struct functor {
template <class X>
auto operator()(int i, X& x) {
return x.increment(i);
}
};
एक पक्ष टिप्पणी के रूप में: T.C. एक comment में बताया गया है, एक कठिन त्रुटि भी निम्न कार्य के लिए होता है ऑब्जेक्ट प्रकार: फिर, सभी fold
भार के अपने-अपने प्रकार के साथ result_of::fold
वर्ग टेम्पलेट का दृष्टांत की जरूरत है:
struct functor {
int operator()(int i, Silly& x) {
return x.increment(i);
}
};
कारण यह विफल रहता है अलग है, हालांकि है। यह वर्ग टेम्पलेट तत्काल संदर्भ में प्रतिस्थापन त्रुटियों का उत्पादन नहीं करता है: यदि पारित कार्य को पारित तर्क प्रकारों के साथ नहीं कहा जा सकता है, तो एक कठिन त्रुटि उत्पन्न होगी।
int(int, Silly&)
प्रकार के फ़ंक्शन के प्रकार int
और के तर्कों के साथ नहीं कहा जा सकता है, तो एक कठिन त्रुटि होती है।
जब एक टेम्पलेट के रूप में ऑपरेटर का प्रयोग (सी ++ 14 वापसी प्रकार कटौती के साथ उदाहरण के रूप में) लेखन, operator()
टेम्पलेट के घोषणा प्रकार का एक दूसरा तर्क के लिए instantiated जा सकता है (X
निष्कर्ष निकाला की जाएगी Silly const
होने के लिए)। फ़ंक्शन परिभाषा को तत्काल नहीं किया जा सकता है, हालांकि, इसके परिणामस्वरूप OP: Silly::increment
में एक ही त्रुटि होगी जिसके परिणामस्वरूप गैर-कॉन्स Silly
ऑब्जेक्ट की आवश्यकता होती है।
फ़ंक्शन की परिभाषा का तत्कालता केवल ओवरलोड रिज़ॉल्यूशन के बाद होती है यदि कोई वापसी प्रकार कटौती नहीं है। इसलिए, यह प्रतिस्थापन विफलताओं का उत्पादन नहीं करेगा।
@ टी.सी. ओह, धन्यवाद। – dyp
इसे रिटर्न प्रकार कटौती के साथ करना है। यह तत्काल संदर्भ में एक प्रतिस्थापन विफलता पैदा नहीं करता है। सबूत: स्पष्ट रूप से लैम्ब्डा के रिटर्न प्रकार को निर्दिष्ट करें, और यह ठीक काम करता है। – dyp
@ dyp ~: धन्यवाद, यह काम करता है। यदि आप इसे उत्तर देते हैं तो मैं इसे स्वीकार करूंगा :) क्या आप यह भी बता सकते हैं कि यह वास्तव में कहां विफल रहता है? धन्यवाद फिर से – linuxfever