2015-09-15 20 views
6

प्रसंगफॉरवर्ड सदस्य समारोह

मूल रूप से मैं, क्योंकि वह एक तीसरी पार्टी पुस्तकालय के लिए पारित किया जाना है (एक सदस्य समारोह के लिए एक const void *const की आवश्यकता है जिसका मतलब है कि मैं उपयोग नहीं कर सकते bind, function, आदि)। चूंकि यह असंभव प्रतीत होता है, मैं अगली सबसे अच्छी चीज करना चाहता हूं और एक स्थिर फ़ॉरवर्डिंग विधि में सदस्य फ़ंक्शन को मैप करना चाहता हूं, जिसके बाद मैं पॉइंटर प्राप्त कर सकता हूं (this को पहले तर्क के रूप में पास कर रहा हूं)।

प्रश्न

मैं कार्यों है कि मैं अलग हस्ताक्षरों के साथ, रजिस्टर करने की आवश्यकता का एक बहुत है, तो मैं एक अच्छा समाधान मुझे में एक सदस्य समारोह की एक हस्ताक्षर कन्वर्ट करने के लिए अनुमति देता है कि करना चाहते हैं एक स्थिर विधि हस्ताक्षर (पाठ्यक्रम के तर्क के रूप में this गुजर रहा है) - जिसे मैं const void* const पर डाल सकता हूं। तो बुनियादी तौर पर मैं इस तरह कुछ करना चाहता हूँ:

तो मूल रूप से:

struct Foo 
{ 
    MyType Bar(int a); 
}; 

template <typename Ret, typename This, Ret(This::*Func)()> 
struct CallWrap0 
{ 
    static Ret &&Call(This* thisPtr) 
    { 
     return thisPtr->(*Func)(); 
    } 
}; 

int Main() 
{ 
    const void * const memberFunction = &(CallWrap0<MyType, Foo, Foo::Bar>()::Call); 
    // etc. 
} 

इस समाधान के साथ समस्या यह है कि है - भले ही यह काम करता है - यह बहुत अच्छा नहीं है, क्योंकि मैं स्पष्ट रूप से संकलक बताने के लिए है प्रकार मैं एक समाधान की तलाश में हूं जहां संकलक स्वचालित रूप से सभी नलसाजी भर सकते हैं।

मैं अब तक भाग्य के बिना, एक सहायक समारोह के साथ इस को हल करने के करने का प्रयास किया गया है:

template <class Ret, class T, class... Args> 
const void* const FunctionPtr(Ret (T::*function)(Args... args)) 
{ 
    // not sure... function is not a template, so this would require a class instance 
    // which is not possible due to the ext. library constraints. 
} 

उत्तर

4
#include <utility> 

template <typename T, T t> 
struct CallWrap; 

template <typename Ret, typename This, typename... Args, Ret(This::*Func)(Args...)> 
struct CallWrap<Ret(This::*)(Args...), Func> 
{ 
    static Ret Call(This* thisPtr, Args... args) 
    { 
     return (thisPtr->*Func)(std::forward<Args>(args)...); 
    } 
}; 

int main() 
{ 
    auto f = &CallWrap<decltype(&Foo::Bar), &Foo::Bar>::Call; 
} 

DEMO


MSVC है, जो ऊपर संकलित करने के लिए विफल रहता है के लिए समाधान, नीचे दिए गए कोड को आजमाएं:

template <typename T> 
struct CallWrap; 

template <typename Ret, typename This, typename... Args> 
struct CallWrap<Ret(This::*)(Args...)> 
{ 
    template <Ret(This::*Func)(Args...)> 
    struct Function 
    { 
     static Ret Call(This* thisPtr, Args... args) 
     { 
      return (thisPtr->*Func)(std::forward<Args>(args)...); 
     } 
    }; 
}; 

int main() 
{ 
    auto f = &CallWrap<decltype(&Foo::Bar)>::Function<&Foo::Bar>::Call; 
} 

DEMO 2

+0

अच्छा, मैंने 'decltype' का उपयोग करने का विचार नहीं किया होगा। मुझे लगता है कि काम करेगा। – atlaste

+0

@atlaste अद्यतन देखें –

+0

बहुत बढ़िया, बस इसका परीक्षण किया, यह ठीक काम करता है। मैं खुशी से इसे स्वीकार करूंगा, बहुत बहुत धन्यवाद! – atlaste

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