std::函数参数子类

std::function parameter subclass

本文关键字:子类 参数 函数 std      更新时间:2023-10-16

我一直试图避免使用C风格的函数指针来支持std::函数对象,但在继承时调用成员函数时遇到了问题。

我有一个接收std::function:的方法

class A
{
public:
    void testCallbackA();
    // this is unrelated, but I need some features from the superclass
    void goingToNeedThisWhenCallingTestCallbackA(int someParams); 
};
void method(std::function<void(A*)> callback);
method(&A::testCallbackA); // this works fine 

现在一切都很好,但当我想用方法使用A子类时,我需要转换函数指针:

class B : public A
{
public:
    void testCallbackB() { }
};
method(&B::testCallbackB); // this fails
std::function<void(A*)> call = &B::testCallbackB; // this fails
std::function<void(B*)> call = &B::testCallbackB; // this works

如果我想能够调用方法(&B::testCallbackB),我需要键入一个函数指针,并以这种方式进行强制转换:

typedef void (A::*Callback)();
std::function<void(A*)> call = (Callback)&B::testCallbackB; // this works

我能避开这个typedef吗?我能避开演员阵容吗?我试着调查std::绑定,但运气不好。

有什么想法吗?

此转换应该失败,因为这是个坏主意。std::function<void(A*)>可与任意A*一起调用,无论所指向的实际对象是否为B。在不是BA上调用B成员函数的结果是未定义的行为。

您可能需要std::bind,就像中一样

B b;
method(std::bind(&B::testCallbackB, b));

如果我很理解您的问题,那么我建议您将类A中的testCallbackA设置为虚拟,然后简单地使用&A: :testCallback调用方法时的A。

动态方法调度将负责调用实际类的方法,并且您不必手动规避类型安全。