如何检查std :: function是否绑定到特定对象的成员函数?

时间:2014-10-24 01:05:15

标签: c++11 callback function-pointers

我正在寻找一种检查std :: function指针是否绑定到特定对象的成员函数的方法。我知道std :: function本身没有'=='运算符。然而,我遇到了std :: function :: target方法,它原则上应该能够给出指针所指向的函数的地址。因此,我的出发点是:

bool MyClass::isThePointerSetToMyMethod(std::function<void (const char*, string)> const& candidate)
{
    // Create a pointer to the local reportFileError function using the same syntax that we did in the constructor:
    std::function<void (const char *, string)> localFn = std::bind(&MyClass::theLocalMember, this, 
                                                                   std::placeholders::_1, std::placeholders::_2);

    // Find the target
    auto ptr1 = localFn.target< std::function<void (const char *, string)> >();

    // Find the target of the candidate 
    auto ptr2 = candidate.target< std::function<void (const char *, string)> >();

    // Compare the two pointers to see whether they actually point to the same function:
    if (!ptr1 || !ptr2) return false;
    if (*ptr1 == *ptr2)
        return true;
    else
        return false;
}

这不起作用,原因是'ptr1'和'ptr2'的值总是返回null。根据{{​​3}},这必须是因为我为目标指定的类型不正确。

如果我看一下target_type(localFn)究竟是什么(使用Visual C ++ 2013),那就太可怕了:

class std::_Bind<1,void,struct std::_Pmf_wrap<void (__thiscall MyClass::*)(char const *, string),void,class MyClass,char const *,string>,class MyClass * const,class std::_Ph<1> &,class std::_Ph<2> &>

尽管如此,target_type(候选者)给出了相同的结果,所以我想我会尝试一个typedef:

bool MyClass::isThePointerSetToMyMethod(std::function<void (const char*, string)> const& candidate)
{
    typedef class std::_Bind<1,void,struct std::_Pmf_wrap<void (__thiscall MyClass::*)(char const *, string),void,class MyClass,char const *,string>,class MyClass * const,class std::_Ph<1> &,class std::_Ph<2> &> wally;

    // Create a pointer to the local reportFileError function using the same syntax that we did in the constructor:
    std::function<void (const char *, string)> localFn = std::bind(&MyClass::theLocalMember, this, 
                                                                   std::placeholders::_1, std::placeholders::_2);

    // Find the target
    auto ptr1 = localFn.target< wally >();

    // Find the target of the candidate 
    auto ptr2 = candidate.target< wally >();

    // Compare the two pointers to see whether they actually point to the same function:
    if (!ptr1 || !ptr2) return false;
    if (*ptr1 == *ptr2)
        return true;
    else
        return false;
}
唉,这让我没有进一步; ptr1和ptr2的值仍然为空。

所以现在我的想法已经用完了。是否有人读到这个谁知道:

(1)std :: function指向类的成员函数的typedef的适当形式,或

(2)实现我的最终目标的更好方法,即判断std :: function指针是指向特定对象的成员函数还是指向它?

[后台,如果有人感兴趣:我这样做的原因是我有一个回调表,根据系统所处的状态,不同的回调被设置为不同的函数;这使得状态控制非常简单,因为这意味着在给定的上下文中我可以调用给定的回调并且知道我调用的函数所采取的操作将适合当前状态,而不必知道任何关于什么的国家实际上是。通常,当实例化一个会改变系统状态的对象时,它会控制相关的回调并将它们绑定到适合于它所处状态的任何本地成员函数。但是,在这些情况下,对象的析构函数应该是将回调返回到状态现状,以便它们不会指向任何内容。

对象很少会在其构造函数中将回调绑定到其成员函数,但在调用析构函数之前,另一个对象可能会控制相同的回调本身,并将它们重新绑定到自己的成员函数。如果发生这种情况,那么第一个对象的析构函数需要能够识别出这种情况已经发生,并在不影响回调对第二个对象方法的赋值的情况下退出。显而易见的方法是让析构函数能够检查回调是否仍然分配给它自己的方法,如果它们不是那么单独留下。]

1 个答案:

答案 0 :(得分:1)

将回调表充实到管理表的类中。对表的所有修改都应该通过这个类的接口完成。在内部,您将维护一个类似堆栈的结构,允许您撤消对回调表所做的更改。 Barebones界面看起来像:

class CallbackTable
{
public:
bool ApplyChanges(...)
{
//Push the old values of the entries that would be changed here into your change-tracker stack and modify the table
}

bool UnApplyChanges(...)
{
//Pop the change-tracker stack and restore the table to the state it was in before the most recent change was applied.
}
};