比较成员函数的 std::function

3
我试图搜索并找到了类似的问题:
问题1
问题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?
附言:我想创建一个简单的委托系统,这样我就可以传递任何函数(全局函数、静态函数、成员函数)了。使用std::function我可以添加回调,但我不知道如何删除它。
2个回答

5

这是因为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;

请注意,如果目标类型实际上是一个类方法,你将不能只使用两个int调用它 - 你还需要ClassA*。例如,this函数的目标类型是int(ClassA::*)(int, int):
function<int(ClassA*, int, int)> f3 = &ClassA::add;

1
int(ClassA*, int, int)本身不是成员函数类型。因此,在这种情况下,std::function目标类型不是成员函数类型。这会影响target成员函数的结果。 - Cheers and hth. - Alf
1
@Cheersandhth.-Alf f3.target_type() == typeid(&ClassA::add) - Barry
你说得对,抱歉。我在想什么呢。你的评论很有帮助。 :) - Cheers and hth. - Alf

2

这些 std::function 并不持有成员函数,它们持有的是 bind 的结果类型。由于 bind 使用了相同的类型模式,所以 bind 的结果类型也是相同的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接