为什么 std::function 不具有可比性?
这个问题也适用于boost::function
和std::tr1::function
.
This question also applies to boost::function
and std::tr1::function
.
std::function
不是等式可比的:
#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
}
在 C++11 中,operator==
和 operator!=
重载是不存在的.在早期的 C++11 草案中,重载被声明为已删除并带有注释 (N3092 §20.8.14.2):
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
它没有说明类型系统中可能存在的漏洞"是什么.是.在 TR1 和 Boost 中,重载已声明但未定义.TR1 规范注释(N1836 §3.7.2.6):
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.
[注意: 类似布尔值的转换打开了一个漏洞,可以通过 ==
或 !=
比较两个函数实例.这些未定义的 void
运算符关闭了漏洞并确保编译时错误.―结束注释]
[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]
我对漏洞"的理解就是如果我们有一个 bool
转换函数,这个转换可以用于相等比较(和其他情况):
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!
}
我的印象是 C++03 中的安全布尔习语和 C++11 中显式转换函数的使用被用来避免这个漏洞".Boost 和 TR1 在 function
中都使用了 safe-bool 习惯用法,C++11 使 bool
转换函数显式化.
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.
作为一个兼具两者的类的例子,std::shared_ptr
都有一个显式的 bool
转换函数并且是相等的.
As an example of a class that has both, std::shared_ptr
both has an explicit bool
conversion function and is equality comparable.
为什么 std::function
不是等式可比的?类型系统中可能存在的漏洞"是什么?它与 std::shared_ptr
有什么不同?
Why is std::function
not equality comparable? What is the "possible hole in the type system?" How is it different from std::shared_ptr
?
推荐答案
为什么是
std::function
不是平等可比的吗?
Why is
std::function
not equality comparable?
std::function
是任意可调用类型的包装器,因此为了完全实现相等比较,您必须要求所有可调用类型都是相等可比较的,从而造成负担在任何实现函数对象的人身上.即便如此,您也会得到一个狭义的相等概念,因为如果(例如)它们是通过以不同顺序绑定参数构造的,则等效函数将比较不相等.我认为不可能在一般情况下测试等效性.
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.
它与std::shared_ptr
有什么不同?一个>?
How is it different from
std::shared_ptr
?
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.
相关文章