आपको यहां से 'MULT गणना * VAL' 'जोड़ी की दूसरी ले' कार्यक्षमता अलग कर सकते हैं और 'एक संचायक के लिए कुछ जोड़ें'।
हालांकि आप यह करने के लिए बढ़ावा देने की जरूरत नहीं है, वे पहले से ही एक 'कार्यात्मक' प्रोग्रामिंग ढांचे के एक महान सौदा बनाया। यदि आप बूस्ट का उपयोग नहीं कर सकते हैं, तो आपको अपने स्वयं के कुछ टेम्पलेट जादू की आवश्यकता है। भी जटिल नहीं है, हालांकि।
// a 'take-second' functor
template< typename at_pair >
struct to_second_t : public std::unary_function< at_pair, typename at_pair::second_type > {
const typename at_pair::second_type& operator()(const at_pair & p) const {
return p.second;
}
};
यह मुश्किल लग रहा है, लेकिन केवल कहने का एक सामान्य तरीका है::
struct SMyStruct
{
int MULT;
int VAL;
long f() const { return MULT*VAL; }
};
'जोड़ी की दूसरी ले' के लिए एक सामान्य functor बनाएँ 'पहले ऐसा करते हैं, तो परिणाम के साथ कि ':
// compose two functors (simplified)
template< typename at_F, typename at_G >
struct compose_t : public std::unary_function< typename at_F::argument_type, typename at_G::result_type >{
at_F f;
at_G g;
compose_t(at_F& f, at_G& g): f(f), g(g) {}
typename at_G::result_type operator()(const typename at_F::argument_type& v) const {
return g(f(v));
}
};
template< typename at_F, typename at_G >
compose_t<at_F, at_G> compose(at_F& f, at_G& g) { return compose_t<at_F,at_G>(f, g); }
// compose two functors (a unary one, and a binary one)
//
template< typename at_F, typename at_G >
struct compose2_t : public std::binary_function< typename at_F::first_argument_type, typename at_G::argument_type, typename at_G::result_type >{
at_F f;
at_G g;
compose2_t(at_F& f, at_G& g): f(f), g(g) {}
typename at_G::result_type operator()(const typename at_F::first_argument_type& a1, const typename at_G::argument_type& v) const {
return f(a1, g(v));
}
};
template< typename at_F, typename at_G >
compose2_t<at_F, at_G> compose2(at_F& f, at_G& g) { return compose2_t<at_F,at_G>(f, g); }
और अंत में, यह सब व्यवहार में डाल:
int main()
{
typedef std::map<int, SMyStruct > tMap;
tMap m;
SMyStruct s = {1,2};
m[1].VAL = 1; m[1].MULT = 3;
m[2].VAL = 2; m[2].MULT = 10;
m[3].VAL = 3; m[3].MULT = 2;
// mind, this is not LISP (yet)
long total = std::accumulate(m.begin(), m.end(), 0,
compose2(
std::plus<int>(),
compose(
to_second_t<tMap::value_type>(),
std::mem_fun_ref(&SMyStruct::f)))
);
std::cout << "total: " << total <<std::endl;
return 0;
}
अरे, बीबी ने मुझे जवाब में हरा दिया, इसलिए मैं इसके बजाय थोड़ा सा पैडेंटिक होने जा रहा हूं: आप जानते हैं कि अग्रणी अंडरस्कोर आम तौर पर एक बुरा विचार है, है ना? (ज्यादातर मामलों में कार्यान्वयन के लिए आरक्षित) और एक संरचना पर एस उपसर्ग पूरी तरह से व्यर्थ शोर है। :) – jalf
अरे, ठीक है ... ठीक है हम एस के साथ हमेशा उपसर्ग structs और वर्गों सी के साथ; हमारे कोडिंग मानक जनादेश। "_" के रूप में, मैं सहमत हूं लेकिन चूंकि यह किसी भी चीज़ का हिस्सा नहीं था, इसलिए मैंने इसे छोड़ दिया। मैं आम तौर पर ग्लोबल्स के लिए सदस्यों g_ और स्थिर के लिए s_ के लिए m_ का उपयोग करता हूं। इस पर ध्यान दिलाने के लिए धन्यवाद। –
_ * शायद * तकनीकी रूप से ठीक हो सकता है। नियम कुछ ऐसा हैं जैसे "डबल अग्रणी _ या अग्रणी _ पूंजी पत्र के बाद कार्यान्वयन के लिए आरक्षित है। अग्रणी _ वैश्विक नामस्थान में आरक्षित है।"सबसे आसान सिर्फ प्रमुख से बचने के लिए _ पूरी तरह है;) – jalf