如何获得C ++模板类来调用另一个类的方法?

时间:2019-02-20 16:52:28

标签: c++ templates pointer-to-member

我有A类,需要调用模板类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

但是它不能完全满足我的需求。上面的代码将如何重写,以便:

  1. 方法bar是类的公共成员,而不是独立的 功能
  2. 传递给方法d
  3. 自变量fbarpublic属于同一类别的bar个成员, 允许bar的类型为void (void)
  4. 对象类型foible是类而不是结构(可选)?

[编辑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...
}

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

2 个答案:

答案 0 :(得分:1)

您使事情变得太复杂了。忘记方法的指针。当前没有理由使用它们。

只需执行以下操作:

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;
}

请注意,这种方法比使用方法指针更灵活,更易读。

答案 1 :(得分:0)

分步解决方案:  所有示例都使用以下类和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;
}