为什么的std ::功能不是平等的可比性? [英] Why is std::function not equality comparable?

查看:170
本文介绍了为什么的std ::功能不是平等的可比性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题也适用于的boost ::功能的std :: tr1 ::功能

的std ::功能不是平等比较的:

 的#include<功能>
无效美孚(){}诠释主(){
    的std ::功能<无效()> F(富),G(富);
    布尔are_equal(F = = G); //错误:f和g没有可比性的平等
}

在C ++ 11的运算符== 运算符!= 重载就是不存在的。在早期的C ++ 11草案,被宣布重载与评论(N3092§20.8.14.2)删除:

  //删除重载尽可能靠近孔类型系统

这并不是说什么在类型系统中可能的漏洞的说法。在TR1和加速,重载声明,但没有定义。 TR1的规范意见(N1836§3.7.2.6):


  

这些成员函数应该没有定义。


  
  

[注:的布尔般的转换打开一个漏洞,即这两个功能实例可以通过进行比较== != 。这些不确定的无效运营商堵塞漏洞,确保编译时错误。的末端笔记的]


我的漏洞的理解是,如果我们有一个布尔转换功能,即转化率可以在平等的比较中使用(而在其他情况下):

 的struct {
    运营商布尔(){返回false; }
};诠释主(){
    S A,B;
    布尔are_equal(一== b)条; //使用布尔运算符A和B!不好了!
}

我是IM pression下,在C ++ 03的安全,布尔成语和C ++ 11的使用显式转换函数的使用,以避免这一漏洞。升压和TR1都使用在函数和C ++ 11的安全,布尔成语使得布尔转换功能明确。

由于同时具有的std :: shared_ptr的 A类的例子既有明确的布尔转换功能是平等的可比性。

为什么的std ::功能不是平等的可比性?什么是在类型系统中可能的漏洞?它是如何从的std :: shared_ptr的

不同
解决方案

  

为什么 的std ::功能 不是平等的可比性?


的std ::功能是任意调用类型的包装,所以为了实现相等比较可言,你就必须要求所有可调用类型是平等的-comparible,放置一个负担实现一个函数对象的人。即使到那时,你会得到平等的狭义的概念,因为如果(例如),他们被以不同的顺序结合参构造同等功能会比较不等。我认为这是不可能的,以测试在一般情况下等价。


  

什么是在类型系统中可能的漏洞?


我想这意味着它更容易删除运营商,并肯定知道使用它们绝不会放弃有效的code,不是要证明有没有一些previously未被发现的角落发生不必要的隐式转换的可能性案例。


  

它是如何从 的std ::不同shared_ptr的


的std :: shared_ptr的有明确界定的平等语义;两个指针相等,当且仅当他们要么都为空,或同时非空,并指向同一个对象。

This question also applies to boost::function and std::tr1::function.

std::function is not equality comparable:

#include <functional>
void foo() { }

int main() {
    std::function<void()> f(foo), g(foo);
    bool are_equal(f == g); // Error:  f and g are not equality comparable
}

In C++11, the operator== and operator!= overloads just don't exist. In an early C++11 draft, the overloads were declared as deleted with the comment (N3092 §20.8.14.2):

// deleted overloads close possible hole in the type system

It does not say what the "possible hole in the type system" is. In TR1 and Boost, the overloads are declared but not defined. The TR1 specification comments (N1836 §3.7.2.6):

These member functions shall be left undefined.

[Note: the boolean-like conversion opens a loophole whereby two function instances can be compared via == or !=. These undefined void operators close the loophole and ensure a compile-time error. —end note]

My understanding of the "loophole" is that if we have a bool conversion function, that conversion may be used in equality comparisons (and in other circumstances):

struct S {
    operator bool() { return false; }
};

int main() {
    S a, b;
    bool are_equal(a == b); // Uses operator bool on a and b!  Oh no!
}

I was under the impression that the safe-bool idiom in C++03 and the use of an explicit conversion function in C++11 was used to avoid this "loophole." Boost and TR1 both use the safe-bool idiom in function and C++11 makes the bool conversion function explicit.

As an example of a class that has both, std::shared_ptr both has an explicit bool conversion function and is equality comparable.

Why is std::function not equality comparable? What is the "possible hole in the type system?" How is it different from std::shared_ptr?

解决方案

Why is std::function not equality comparable?

std::function is a wrapper for arbitrary callable types, so in order to implement equality comparison at all, you'd have to require that all callable types be equality-comparible, placing a burden on anyone implementing a function object. Even then, you'd get a narrow concept of equality, as equivalent functions would compare unequal if (for example) they were constructed by binding arguments in a different order. I believe it's impossible to test for equivalence in the general case.

What is the "possible hole in the type system?"

I would guess this means it's easier to delete the operators, and know for certain that using them will never give valid code, than to prove there's no possibility of unwanted implicit conversions occurring in some previously undiscovered corner case.

How is it different from std::shared_ptr?

std::shared_ptr has well-defined equality semantics; two pointers are equal if and only if they are either both empty, or both non-empty and pointing to the same object.

这篇关于为什么的std ::功能不是平等的可比性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆