2015-02-04 30 views
6

मान लीजिए कि मैं करते हैंखाका गैर प्रकार सूचक

template <void (Foo::*method)()> 
void only_for_a(Foo *f) { 
    (f->*method)(); 
} 

only_for_a<&Foo::a>(&some_foo); 
: और मैं एक समारोह है कि एक टेम्पलेट के रूप सूचक-हैं- Foo विधि का एक विशेष प्रकार लेता है बना सकते हैं 0

लेकिन क्या कोई ऐसा फ़ंक्शन बनाने का कोई तरीका है जिसे मैं पर किसी भी पॉइंटर क्लास विधि पर टेम्पलेट कर सकता हूं? मैं ऐसा करने में सक्षम होना चाहता हूं:

works_for_anything<&Foo::a>(&some_foo); 
works_for_anything<&Foo::b>(&some_foo, 42); 
int result = works_for_anything<&Foo::c>(&some_foo); 
+1

नहीं, गैर-प्रकार के टेम्पलेट पैरामीटर के पास एक निश्चित प्रकार होना चाहिए। तुम ऐसा क्यों करना चाहते हो? – Brian

+0

'टेम्पलेट <टाइपनाम टी, शून्य (टी :: * medhod)()>' – erenon

+0

@erenon मुझे लगता है कि आप 'टेम्पलेट <टाइपनाम टी, टी विधि>' का मतलब मानते हैं, लेकिन फिर कॉलर को प्रकार निर्दिष्ट करना होगा, उदा। 'works_almost (और some_foo, 42);'। लेकिन यह अनावश्यक लगता है। – Barry

उत्तर

0

क्या यह आपके लिए काम करेगा?

template< typename T, T > 
class works_for_anything_t; 

template< typename R, typename... Args, R (*f)(Args...) > 
class works_for_anything_t< R (*)(Args...), f >{ 
public: 
    R operator()(Args... args){ return f(args...); } 
}; 

template< typename T, typename R, typename... Args, R (T::*f)(Args...) > 
class works_for_anything_t< R (T::*)(Args...), f >{ 
public: 
    R operator()(T& v, Args... args) { return (v.*f)(args...); } 

    works_for_anything_t(T& v) 
    : v_(v) { } 
private: 
    T& v_; 
}; 

template< typename T, typename R, typename... Args, R (T::*f)(Args...) const > 
class works_for_anything_t< R (T::*)(Args...) const, f >{ 
public: 
    R operator()(const T& v, Args... args) const { return (v.*f)(args...); } 

    works_for_anything_t(const T& v) 
    : v_(v) { } 
private: 
    const T& v_; 
}; 

#define works_for_anything(f) works_for_anything_t<decltype(&f), &f> 

struct Foo { 
    void a(); 
    void b(const int&); 
    int c(); 
}; 

int test(); 

int main() { 
    Foo foo; 
    works_for_anything(Foo::b){foo}(42); 
    works_for_anything(test){}(); 
    return 0; 
} 
संबंधित मुद्दे