5

के सदस्य-समारोह और सूचक के लिए दोनों सूचक ले रही है मैं निम्नलिखित कोड आधार है:समारोह स्थिरांक सदस्य समारोह

template <typename Type> 
class SomeClass { 
public: 
    template <typename ReturnType, typename... Params> 
    void register_function(const std::pair<std::string, ReturnType (Type::*)(Params...)> fct) { 
     auto f = [fct](Params... params) -> ReturnType { return (Type().*fct.second)(std::ref(params)...); } 
     // ... 
    } 
}; 

यह काम करता है जब मैं एक सदस्य-कार्य करने के लिए एक सूचक पारित (गैर स्थिरांक)। हालांकि, अगर मैं एक स्थिरांक सदस्य-कार्य करने के लिए एक सूचक पास करना चाहते हैं, यह एक संकलन त्रुटि में परिणाम है और मैं ऊपर समारोह नकल करना होगा इस कोड प्राप्त करने के:

template <typename Type> 
class SomeClass { 
public: 
    template <typename ReturnType, typename... Params> 
    void register_function(const std::pair<std::string, ReturnType (Type::*)(Params...)> fct) { 
     auto f = [fct](Params... params) -> ReturnType { return (Type().*fct.second)(std::ref(params)...); } 
     // ... 
    } 

    template <typename ReturnType, typename... Params> 
    void register_function(const std::pair<std::string, ReturnType (Type::*)(Params...) const> fct) { 
     auto f = [fct](Params... params) -> ReturnType { return (Type().*fct.second)(std::ref(params)...); } 
     // ... 
    } 
}; 

अब, मैं दोनों const- पारित कर सकते हैं सदस्य-कार्य और गैर-सदस्य-कार्य-कार्य। लेकिन, अब, कोड डुप्लिकेट है और रखरखाव कम हो गया है।

क्या इन दोनों कार्यों को एक कॉन्स-सदस्य-फ़ंक्शंस और गैर-कॉन्स्ट-सदस्य-फ़ंक्शंस दोनों को फ़ंक्शन में विलय करने का कोई तरीका है?

महत्वपूर्ण नोट: मुझे वास्तव में पैरामीटर के रूप में एक सूचक कार्य लेना चाहिए (कोई std :: function)।

संपादित करें: मैंने थोड़ा और कोड जोड़ा है। फ़ंक्शंस के अंदर, मैं सदस्य फ़ंक्शन हस्ताक्षर (समान रिटर्न प्रकार और पैरा) से मेल खाता बंद करता हूं। यह बंद संग्रहीत और प्रतिबिंब बनाने के लिए बाद में इस्तेमाल किया जाएगा (more here)

+0

क्यों नहीं बस 'टेम्पलेट शून्य register_function (मज़ा एफसीटी)'? – fredoverflow

+0

मैंने अपने प्रश्न को थोड़ा और कोड के साथ अपडेट किया है। लैम्बडास के अंदर, मैं std :: bind को कॉल कर सकता हूं या किसी नए ऑब्जेक्ट उदाहरण पर सदस्य फ़ंक्शन पॉइंटर का सीधे उपयोग कर सकता हूं। यही कारण है कि मुझे वास्तव में रिटर्नटाइप और पैराम्स टाइपनामों तक पहुंचने की आवश्यकता है। –

+0

क्या यह आपका पूरा कोडबेस है? lol वास्तव में –

उत्तर

5

आप एक प्रकार विशेषता बारे में है, जो आपको बता देंगे के आधार पर सकता है अगर कुछ MFType पर एक सूचक करने वाली सदस्य समारोह है:

template <typename C, typename T> 
struct is_pointer_to_member_helper : std::false_type { }; 

template <typename C, typename T> 
struct is_pointer_to_member_helper<C, T C::*> : std::is_function<T> { }; 

template <typename C, typename T> 
struct is_pointer_to_member : is_pointer_to_member_helper<C, 
            std::remove_cv_t<T> 
           > { }; 

और इसका इस्तेमाल सुनिश्चित करने के लिए है कि आप केवल उन में से एक मिलता है:

template <typename Type> 
class SomeClass { 
public: 
    template <typename MF> 
    std::enable_if_t<is_pointer_to_member<Type, MF>::value> 
    register_function(const std::pair<std::string, MF> fct) 
    { 
     auto f = [fct](auto&&... params) { 
      return (Type{}.*fct.second)(std::forward<decltype(params)>(params)...); 
     }; 

     // ... 
    } 
}; 
+0

में मदद करेगा हमारे पास 'std :: is_member_function_pointer' –

+0

@ टी.सी. है। उसे नहीं पता था। मुझे लगता है कि अभी भी स्पष्ट रूप से जांचना है कि कौन सा वर्ग सदस्य सदस्य का सूचक है। – Barry

+0

दिलचस्प जवाब। हालांकि, मुझे रिटर्नटाइप और पैराम्स ... टाइपनामों तक पहुंचने की आवश्यकता है। मैंने अपने प्रश्न को थोड़ा और कोड के साथ अपडेट किया है: मैं अपने कोड में लैम्ब्डा का उपयोग करता हूं जहां मैं std :: bind को कॉल कर सकता हूं या फ़ंक्शन पॉइंटर को नए प्रकार के उदाहरण पर सीधे उपयोग कर सकता हूं। –

संबंधित मुद्दे