如何让 C++ 模板 class 调用另一个 class' 方法?

How to get a C++ template class to invoke another class' methods?

我有 class A 需要调用模板的成员函数 class B。四处搜索我在这个网站上找到了这个示例代码:

#include <iostream>

template<typename T, typename FType>
void bar(T& d, FType f) {
  (d.*f)(); // call member function
}

struct foible
{
  void say()
  {
    std::cout << "foible::say" << std::endl;
  }
};

int main(void)
{
  foible f;
  bar(f,  &foible::say); // types will be deduced automagically...
}

来自这个答案: C++ method name as template parameter

但它并没有 100% 满足我的需求。如何重写上面的代码,以便:

  1. 方法 bar 是 class 的 public 成员,而不是独立的 函数
  2. 传递给方法 bar 的参数 dfpublic 同一个 class 的成员,bar 是其中的成员, 允许 barvoid (void)
  3. 类型
  4. 对象类型 foible 是 class 而不是结构(可选)?

[编辑 1] 我自己的重写尝试满足点 1) 和 2) 如下,这是错误的:

#include <iostream>

template<class T, void (T::*FType)()>
class foo {
public:
  T obj;
  FType f;
void bar(void) {
  (obj.*f)(); // call member function
} // end bar
}; // end class foo

struct foible
{
  void say()
{
  std::cout << "foible::say" << std::endl;
}
};

int main(void)
{
foible f;
foo<foible, void (foible::*)()> c;
c.T = f;
c.Ftype = &foible::say;

c.bar(); // types will be deduced automagically...
}

我的目标是让class类型的对象'A'调用class类型'B'对象的方法,这样当这些方法执行对象时类型 'B' 可以使用其 'this' 指针来引用其本地数据。我想在 class 类型 'A' 中使用函数指针,这样它们只需要指定一次,我不希望一个 class 必须从另一个派生。

你把事情搞得太复杂了。忘掉指向方法的指针。目前没有理由使用它们。

就像这样:

template<typename F>
void bar(F f) {
  doSomething();

  f(someArg);

  doSomething();
}

int main(void)
{
  foible f;
  bar([&f](auto x) { f.someMagicMethod(x); } );

  return 0;
}

请注意,与使用方法指针相比,此方法更灵活且可读性更高。

分步解决方案: 所有示例都使用以下 class 和 foo 函数

#include <iostream>
class A
{
public:
    void foo(){std::cout<<"foo"<<std::endl;}
};

此示例在没有模板的情况下工作:只需使用指向 A 和指向 A::foo 的指针调用调用 A::foo:

class B
{
public:
    A *a;
    void (A::*p)(); 

    void bar()
    {
        (a->*p)(); //call A::foo 
    }
};
int main(void)
{
    A a;
    B b;
    b.a = &a;
    b.p = &A::foo;
    b.bar();
    return 0;
}

以下示例添加了模板 class T,指向派生自 T 的 foo 方法的指针。

template <class T>
class C
{
public:
    T* t;
    void (T::*p)(); 
    C(T &o) : t(&o){} 
    void bar()
    {
        (t->*p)();
    }
};
int main(void)
{
    A a;
    C<A> c(a);
    c.p = &A::foo;
    c.bar();
    return 0;
}

在下面,方法指针也被模板化了,但我不知道如何使用它,因为你应该知道给它多少参数,但无论如何:

template <class T, typename F>
class D
{
public:
    T* t;
    F p; 
    D(T &o, F pf) : t(&o),p(pf){} 
    void bar()
    {
        (t->*p)();
    }
};
int main(void)
{
    A a;
    D<A, void (A::*)()> d(a, &A::foo);
    d.bar();
    return 0;
}