比较成员函数的std :: function

时间:2015-01-06 11:59:08

标签: c++ function c++11 function-pointers

我试着在这里搜索类似的问题:
question 1
question 2

但无论如何,我无法比较成员函数。这是一个例子:

class ClassA
{
public:
    int add(int a, int b)
    {
        return a + b;
    }
};

int main()
{
    ClassA a1{};

    function<int(int, int)> f1 = bind(&ClassA::add, a1, placeholders::_1, placeholders::_2);
    function<int(int, int)> f2 = bind(&ClassA::add, a1, placeholders::_1, placeholders::_2);

    cout << boolalpha << "f1 == f2 " << (f1.target_type() == f2.target_type()) << endl; // true
    cout << (f1.target<int(ClassA::*)(int, int)>() == nullptr) << endl; // true

    return 0;
}

从代码中可以看出, f1 f2 是不同的。第一个 cout 显示 true ,因为类型相同,没关系。但为什么第二个 cout true ?为什么 function :: target()会返回 nullptr

P.S。:我想创建一个简单的委托系统,这样我就可以传递任何函数(全局,静态,成员)。使用 std :: function ,我可以添加一个回调,但我不知道如何删除它。

2 个答案:

答案 0 :(得分:4)

那是因为f1的目标类型不是int(ClassA::*)(int, int)。它的目标类型将是bind表达式的结果,它在gcc上恰好是:

std::_Bind<std::_Mem_fn<int (ClassA::*)(int, int)> (
    ClassA, 
    std::_Placeholder<1>, 
    std::_Placeholder<2>)>

您可以使用ABI demangler查看:

#include <cxxabi.h>
// note, the following line technically leaks, but 
// for illustrative purposes only it's fine
cout << abi::__cxa_demangle(f1.target_type().name(), 0, 0, 0) << endl;

请注意,如果目标类型实际上是一个类方法,那么您将无法使用两个int来调用它 - 您还需要ClassA*。例如,函数的目标类型为int(ClassA::*)(int, int)

function<int(ClassA*, int, int)> f3 = &ClassA::add;

答案 1 :(得分:2)

那些std::function不包含成员函数。他们持有bind个结果类型。由于bind是相同的类型模式,bind结果类型是相同的。