我试图在C ++中存储指向不同类的成员函数的指针。 C ++有哪些可能性?
我想这样做:
class A {
T0 f(T1,T2);
};
class B {
T0 g(T1,T2);
T0 h(T1,T2); //interfaces cant be used since the number of functions per class differs.
};
typedef WHATTOPUTHERE type;
type x;
x = A::f;
x = B::h;
更新:另一个问题是代码应该像这样继续:
B myB;
myB::x(a,b); //not sure about the syntax, should result in myB::h(a,b) being called
这意味着我可以在存储指针时不绑定,因为实例不存在(还)。
答案 0 :(得分:4)
封装函数指针的函数对象应该可以工作。
boost::function是一个选项,可能是这样的:
class SomeObj
{
public:
void SetInt(int i);
};
SomeObj myObject;
std::vector<boost::function> memberFuncs;
// in the template arg to boost::bind specify the function type
// _1 here denotes late binding so you can pass whatever value you want when invoked
// you could simply bind a parameter as a variable or literal instead
memberFuncs.push_back(boost::bind<void(int)>(&SomeObj::SetInt, &myObject, _1));
memberFuncs[0](42); // myObject->SetInt(42);
未经测试/未编译的代码免责声明这只是一般性的想法。
答案 1 :(得分:1)
使用std :: function和lambda可以很容易地完成一个可能的实现(使用C ++ 11):
typedef std::function<void(int)> FunctionType;
SomeClass someClass;
FunctionType func = [&someClass](int argument)
{
someClass.SomeMemberFunction(argument);
};
答案 2 :(得分:0)
要有一个指向Fred :: f(char,float)的指针,你需要这种指针:
int (Fred::*)(char,float)
http://www.parashift.com/c++-faq-lite/pointers-to-members.html
答案 3 :(得分:0)
您的特定问题的答案是没有类型可以添加到typedef并使代码编译。原因是成员函数指针采用了获取它们的类形式类型的隐藏参数。当您从A
或B
获取成员函数的地址时,该隐藏参数的类型将有所不同。
接下来的问题是从设计的角度来看它是否有意义,考虑到你不能将函数指针A::f
应用于类型B
的实例,考虑成员指针的重点是什么A
和B
在一起?
现在,对于这个特定问题(如果它在你的情况下有意义,但我会首先审查设计)有可能的解决方法,涉及对函数指针执行类型擦除以删除隐藏参数并生成一个对象可以使用给定的参数集和所有成员函数共有的返回类型进行调用。这已在std::function
内完成(如果您的编译器不支持C ++ 11,则可选boost::function
),如前所述:
A a_instance;
std::function< T0 (T1,T2) > f( std::bind( &A::f, &a_instance, _1, _2 ) );
T0 r = f( T1(), T2() );
请注意,部分技巧是std::bind
使用指向实例的指针绑定成员函数指针,填充隐藏参数,同时保留其他两个参数不绑定。此时,由于bind
的结果不再依赖于第一个参数的类型,因此可以应用 type-erasure 从结果类型中删除A
对象