C++11如何判断std::bind,std::function对象是否相等
转载请注明 作者:源码先生, 文章链接:https://www.debugself.com/2017/09/17/cpp_bind_fun_eq/, 请勿用于商业用途
如何判断两个bind对象是否相等
先上结论:无法判断
bind函数返回一个bind对象,这个bind对象具体是什么类型呢?查找下bind的参考文档,比如MSDN中bind函数定义如下
1 | template<class Fty, class T1, class T2, ..., class TN> |
纳尼?返回值类型为unspecified ?返回值类型未定义!没关系,自己写个Demo来获取bind的返回类型。
1 | void print_add(int i, int j) { |
上面的Demo中,decltype可以获取表达式的类型,通过decltype我们最终得到了bind返回值类型为std::_Binder,_Binder下划线告诉我们这个类是一个内部类,并不开放给开发者。
由于std::_Binder并没有重载==运算符,所以无法判断两个bind对象是否相等;std::_Binder也没有提供获取构造bind对象时的函数指针(如无法通过f1获取到构造f1的print_add地址)的接口,所以也不能判断bind对象内部函数指针是否相等。
如何判断两个function对象是否相等
function提供了function::target函数获取function内部保存的可调用对象的指针.
1 | void print(int i) { |
需要注意的是,上面的代码中f1.target<void()(int)>中指明target的类型是void()(int),这个类型即print的函数指针,如果类型填写错误,target的返回值为空。
1 | int main(){ |
之所以类型填写错误,target的返回值为空,是因为target函数内部会先获取function内部可调用对象的真正类型,然后对比该类型和f1.target<void(*)(int)>指定的类型是否不一致,不一致时直接返回空指针。 所以,要判断function内部指针是否相等,前提条件是f1.target的类型必须相同!像下面的两个function对象
1 | Callback_Fun f1 = print; |
虽然f1和f2都是由print函数构造出来的,但是f1和f2是必定不相等的,因为f1的内部target类型是一个函数,而f2的内部target类型是一个bind对象,两者的类型是不一样的,target的返回值必定也是不一样的。 即使两个function对象内部都是bind对象,如下
1 | Callback\_Fun f1 = bind(print,std::placeholders::\_1) |
尽管f1.target、f2.target类型相同,也可以获取到两者的可调用对象的地址,但是因为f1.target、f2.target的返回值为bind对象,且无法判断两个bind对象是否相等,所以依旧无法判断f1和f2是否相等。
结论:只有当function对象内部是函数指针时,才可以判断function对象是否相等,function内部是bind对象或者lambda对象时,都是无法判断function对象是否相等的。 无法判断两个bind,function对象是否相等,如果非要判断,只能自己来判断了,比如自己把构造多个bind对象的函数指针保存起来,然后自己对比函数指针是否相等。