कई अच्छे जवाब पहले से ही हैं, इसलिए मेरा आपके सवाल का एक सबसेट को संबोधित करेगा; अर्थात्, मैं आपके प्रश्न के आधार पर umbrage लेता हूं, क्योंकि OOP और कार्यात्मक विशेषताएं परस्पर अनन्य नहीं हैं।
यदि आप C ++ 11 का उपयोग करते हैं, तो भाषा / मानक पुस्तकालय में निर्मित कार्यात्मक-प्रोग्रामिंग सुविधाओं के इन प्रकार के बहुत सारे हैं जो OOP के साथ अच्छी तरह से तालमेल (सुंदर) करते हैं। बेशक, मुझे यकीन नहीं है कि टीएमपी आपके बॉस या सहकर्मियों द्वारा कितनी अच्छी तरह से प्राप्त किया जाएगा, लेकिन मुद्दा यह है कि आप इनमें से कई सुविधाओं को किसी न किसी रूप में गैर-कार्यात्मक / ओओपी भाषाओं में प्राप्त कर सकते हैं, जैसे कि सी ++।
संकलित समय पुनरावृत्ति के साथ टेम्पलेट्स का उपयोग करना आपके पहले 3 बिंदुओं पर निर्भर करता है,
- अचल स्थिति
- प्रत्यावर्तन
- पैटर्न मिलान
उस टेम्पलेट-मान में अपरिवर्तनीय (संकलन-समय स्थिरांक) हैं, किसी भी पुनरावृत्ति का उपयोग पुनरावृत्ति का उपयोग करके किया जाता है, और ब्रोचिंग को अधिभार संकल्प के रूप में (अधिक या कम) पैटर्न मिलान का उपयोग करके किया जाता है।
अन्य बिंदुओं के लिए, का उपयोग करके std::bind
और std::function
आपको आंशिक फ़ंक्शन अनुप्रयोग देता है, और फ़ंक्शन पॉइंटर्स भाषा में अंतर्निहित होते हैं। कॉल करने योग्य ऑब्जेक्ट कार्यात्मक ऑब्जेक्ट (साथ ही आंशिक फ़ंक्शन अनुप्रयोग) हैं। ध्यान दें कि कॉल करने योग्य वस्तुओं से मेरा मतलब है कि उनकी परिभाषा operator ()
।
आलसी मूल्यांकन और शुद्ध कार्य थोड़ा कठिन होगा; शुद्ध कार्यों के लिए, आप लैम्ब्डा कार्यों का उपयोग कर सकते हैं, जो केवल मूल्य से कैप्चर करते हैं, लेकिन यह गैर-आदर्श है।
अंत में, यहाँ आंशिक फ़ंक्शन अनुप्रयोग के साथ संकलन-समय पुनरावृत्ति का उपयोग करने का एक उदाहरण है। यह कुछ हद तक विरोधाभासी उदाहरण है, लेकिन यह ऊपर के अधिकांश बिंदुओं को प्रदर्शित करता है। यह एक दिए गए फ़ंक्शन के लिए एक दिए गए टपल में मानों को पुन: बाँध देगा और एक (कॉल करने योग्य) फ़ंक्शन ऑब्जेक्ट उत्पन्न करेगा
#include <iostream>
#include <functional>
//holds a compile-time index sequence
template<std::size_t ... >
struct index_seq
{};
//builds the index_seq<...> struct with the indices (boils down to compile-time indexing)
template<std::size_t N, std::size_t ... Seq>
struct gen_indices
: gen_indices<N-1, N-1, Seq ... >
{};
template<std::size_t ... Seq>
struct gen_indices<0, Seq ... >
{
typedef index_seq<Seq ... > type;
};
template <typename RType>
struct bind_to_fcn
{
template <class Fcn, class ... Args>
std::function<RType()> fcn_bind(Fcn fcn, std::tuple<Args...> params)
{
return bindFunc(typename gen_indices<sizeof...(Args)>::type(), fcn, params);
}
template<std::size_t ... Seq, class Fcn, class ... Args>
std::function<RType()> bindFunc(index_seq<Seq...>, Fcn fcn, std::tuple<Args...> params)
{
return std::bind(fcn, std::get<Seq>(params) ...);
}
};
//some arbitrary testing function to use
double foo(int x, float y, double z)
{
return x + y + z;
}
int main(void)
{
//some tuple of parameters to use in the function call
std::tuple<int, float, double> t = std::make_tuple(1, 2.04, 0.1);
typedef double(*SumFcn)(int,float,double);
bind_to_fcn<double> binder;
auto other_fcn_obj = binder.fcn_bind<SumFcn>(foo, t);
std::cout << other_fcn_obj() << std::endl;
}