为什么std :: function不等于相等?

这个问题也适用于boost::function和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):


// deleted overloads close possible hole in the type system

它没有说“类型系统中可能的孔”是什么。在TR1和Boost中,已声明但未定义重载。TR1规范注释(N1836§3.7.2.6):


这些成员函数应保持未定义状态。


[ 注意:类似布尔的转换打开了一个漏洞,可以通过==或比较两个函数实例!=。这些未定义的void运算符消除了漏洞,并确保了编译时错误。—尾注 ]


我对“漏洞”的理解是,如果我们有bool转换函数,则该转换可用于相等比较(和其他情况):


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而C ++ 11使bool转换函数明确。


作为同时具有两者的类的示例,std::shared_ptr两者都具有显式bool转换函数并且具有相等的可比性。


为什么std::function平等不具有可比性?什么是“类型系统中可能的孔”?std::shared_ptr有何不同?


米脂
浏览 1044回答 3
3回答

三国纷争

为什么std::function平等不具有可比性?std::function是用于任意可调用类型的包装,因此,要完全实现相等性比较,您必须要求所有可调用类型都具有相等性,从而给实现函数对象的任何人带来负担。即使那样,您也会得到一个狭义的等式概念,因为如果(例如)等效函数是通过以不同顺序绑定参数构造的,则等效函数会比较不等式。我认为,在一般情况下无法测试等效性。什么是“类型系统中可能的孔”?我想这意味着删除操作符,并确定使用它们永远不会给出有效的代码,比证明在某些以前未发现的极端情况下不存在不必要的隐式转换的可能性要容易得多。std::shared_ptr有何不同?std::shared_ptr具有明确定义的相等语义;当且仅当两个指针均为空或非空且指向同一对象时,两个指针才相等。

料青山看我应如是

我可能错了,但是我认为std::function对象的相等性在一般意义上是不可解决的。例如:#include <boost/bind.hpp>#include <boost/function.hpp>#include <cstdio>void f() {&nbsp; &nbsp; printf("hello\n");}int main() {&nbsp; &nbsp; boost::function<void()> f1 = f;&nbsp; &nbsp; boost::function<void()> f2 = boost::bind(f);&nbsp; &nbsp; f1();&nbsp; &nbsp; f2();}是f1和f2等于?如果我添加任意数量的函数对象,这些对象以各种方式相互包装,最终归结为对f... 的调用仍然相等,该怎么办?
打开App,查看更多内容
随时随地看视频慕课网APP