【问题标题】:Comparing std::function for member functions比较成员函数的 std::function
【发布时间】:2015-03-04 02:14:13
【问题描述】:

我试图搜索和这里类似的问题:
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;
}

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

    您可以使用 ABI 拆解器看到:

    #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;
    

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

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

    【讨论】:

    • int(ClassA*, int, int) 本身不是成员函数类型。所以std::function 目标类型在这种情况下不是成员函数类型。这会影响target 成员函数的结果。
    • @Cheersandhth.-Alf f3.target_type() == typeid(&amp;ClassA::add)
    • 你是对的,对不起。我在想什么。对您的评论 +1。 :)
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 1970-01-01
      • 2011-08-16
      • 2012-08-22
      • 1970-01-01
      • 1970-01-01
      • 2015-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多