为什么std::function::argument_type已被弃用?

25

我在cppreference上看到 std::function::argument_type 在C++17中被弃用了。这是什么原因?提出这一建议的ISO WG21文件是什么?

2个回答

24
相关的论文是 P0005R4(这是被选入草案标准的论文)和 P0090R0(被 P0005R4 引用的论文)。
来自 P0090R0 的引用:

Q2. result_type 等有什么问题?

A2. 这些 C++98/03/TR1 时代的 typedef 在 decltype 和完美转发之前就存在了。以前,通用代码必须先从函数对象请求信息才能对其进行调整。现在,手动传递该信息是不必要的。decltype 取代了 result_type,因为编译器可以简单地报告使用特定参数调用函数对象的结果。完美转发取代了 argument_type 系列,因为适配器可以简单地接收/存储/转发任意参数。

事实上,这些 typedef 不仅无用,而且还有害。它们是有害的,因为许多可调用对象缺少它们。函数指针和成员指针一直缺乏它们。ptr_fun() 最近被移除了(再次见 [1])。最重要的是,lambda 一直缺少这些 typedef,它们是最重要的函数对象。通用 lambda 更加不兼容。

这意味着,如果用户尝试使用 result_type 等系列的 typedef 来编写通用代码,他们的代码将不是通用的——它将无法处理 lambda、通用 lambda、函数指针等。

应该删除这些 typedef,因为它们已经对现代代码产生了积极的有害作用。


9
这些typedef的存在是为了像not1bind1st和其他类似工具所设计的,可以查询传递给它们的可调用函数并检索调用函数的结果类型、其参数类型等。
为了使它们的使用更加容易,还定义了很多支持机制,如unary_functionptr_funmem_fun等。请注意,所有这些都仅限于只接受一或两个参数的可调用项,因此在这方面它们相当有局限性。
现在我们有了decltype可以推断可调用函数的返回类型,可变参数模板和完美转发可以将任意数量的参数转发到函数中,因此C++11之前的机制已经过时且难以使用。
Stephan T Lavavej首次建议在C++17中摆脱这些功能,在p0090r0中提到了相关的摘录:

Q1. 你提出了什么?
* 删除每个result_typeargument_typefirst_argument_typesecond_argument_type...
* 删除由这些typedef驱动的否定者not1()not2()

Q2. result_type等有什么问题?
A2. 这些C++98/03/TR1时代的typedef是在decltype和完美转发之前定义的。以前,通用代码必须在调整它们之前从函数对象请求信息。现在,手动传递这些信息是不必要的。decltype取代了result_type,因为编译器可以简单地报告调用特定参数的函数对象的结果。完美转发取代了argument_type系列,因为适配器可以简单地获取/存储/转发任意参数。

如果您搜索该文件以查找[func.wrap.func],则它将专门讨论删除您所问及的std::function typedef。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接