【问题标题】: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;

标签: c++ templates c++11


【解决方案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;
}

【讨论】:

    猜你喜欢
    • 2011-04-28
    • 2023-04-07
    • 1970-01-01
    • 2017-10-16
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    相关资源
    最近更新 更多