为什么的std ::功能不是平等的可比性? [英] Why is std::function not equality comparable?
问题描述
这个问题也适用于的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
andstd::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==
andoperator!=
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 undefinedvoid
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 thebool
conversion function explicit.As an example of a class that has both,
std::shared_ptr
both has an explicitbool
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 fromstd::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屋!