指向任意类方法的模板非类型指针

Posted

技术标签:

【中文标题】指向任意类方法的模板非类型指针【英文标题】:Template non-type pointer to arbitrary class method 【发布时间】:2015-04-04 14:39:18 【问题描述】:

假设我有:

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

我可以创建一个函数,该函数将任意指向Foo 方法的指针作为参数:

template <typename R, typename... Formal, typename... Args>
R call(Foo* f, R (Foo::*method)(Formal...), Args&&... args) 
    return (f->*method)(std::forward<Args>(args)...);


int gratuitous = call(&some_foo, &Foo::c);

而且我可以创建一个函数,它采用特定类型的指向Foo 方法的指针作为模板:

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


only_for_a<&Foo::a>(&some_foo);

但是有没有办法创建一个函数,我可以在 any 指向类方法的指针上进行模板化?我希望能够做到:

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

【问题讨论】:

不,非类型模板参数必须具有固定类型。为什么要这样做? template&lt;typename T, void(T::*medhod)()&gt;怎么样 @erenon 我假设你的意思是template &lt;typename T, T method&gt;,但是调用者必须指定类型,例如works_almost&lt;decltype(&amp;Foo::b), &amp;Foo::b&gt;(&amp;some_foo, 42);。但这似乎是多余的。 也许使用 C++1Z:template &lt;using typename R, using typename... Args, R(Foo::*method)(Args...)&gt; 呃,using typename,谁喜欢呢?这些关键字已经被超额订阅。为什么不template &lt;auto Method&gt; 【参考方案1】:

这对你有用吗?

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;

【讨论】:

以上是关于指向任意类方法的模板非类型指针的主要内容,如果未能解决你的问题,请参考以下文章

向模板类传递通用方法的指针。

模板函数将参数函数指针指向类方法

为啥可以从指向实例化基类对象的强制转换指针调用非静态派生类方法?

如何定义和设置指向模板类方法的函数指针

部分模板类中不允许指向不完整类类型的指针

存储指向同一模板类的模板类型的指针