我有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
但是它不能完全满足我的需求。上面的代码将如何重写,以便:
bar
是类的公共成员,而不是独立的
功能d
的f
和bar
是
public
属于同一类别的bar
个成员,
允许bar
的类型为void (void)
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'中使用函数指针,以便只需要指定一次,并且我不希望一个类必须从另一个类派生。
答案 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;
}