【发布时间】:2016-03-10 04:12:50
【问题描述】:
我在 cppreference 上看到 std::function::argument_type 在 C++17 中已被弃用。背后的原因是什么?什么 ISO WG21 论文提出了这个建议?
【问题讨论】:
标签: c++ function language-lawyer deprecated c++17
我在 cppreference 上看到 std::function::argument_type 在 C++17 中已被弃用。背后的原因是什么?什么 ISO WG21 论文提出了这个建议?
【问题讨论】:
标签: c++ function language-lawyer deprecated c++17
相关论文为P0005R4(被投票纳入标准草案的论文)和P0090R0(被P0005R4引用)。
来自 P0090R0 的报价:
第二季度。 result_type等有什么问题?
A2。这些 C++98/03/TR1 时代的 typedef 早于 decltype 和完美 转发。以前,通用代码必须从 在适应它们之前的功能对象。现在,手动通信 这些信息是不必要的。 decltype 取代 result_type, 因为编译器可以简单地报告调用 a 的结果 具有特定参数的函数对象将是。并且完美 forwarding 取代了 argument_type 系列,因为适配器可以 只需获取/存储/转发任意参数。
事实上,这些 typedef 比没用更糟糕。他们是 适得其反,因为许多可调用对象缺少它们。功能 指针和指向成员的指针一直缺少它们。 ptr_fun(), 最近用这些 typedef 包装了函数指针 已删除(再次参见 [1])。最重要的是,lambda 一直缺乏 这些类型定义,它们是最重要的函数对象 全部。泛型 lambda 更加不兼容。
这意味着如果用户尝试通过以下方式编写通用代码 使用 typedef 的 result_type 系列,它们的代码不会是通用的 - 它将无法处理 lambdas、泛型 lambdas、函数指针等。
这些类型定义应该被删除,因为它们已经变得活跃 对现代代码有害。
【讨论】:
这些 typedef 存在的原因是像 not1、bind1st 和朋友这样的东西,可以查询传递给他们的可调用对象并检索调用可调用对象的结果类型、其参数类型等。
为了让它们的使用更可口,还定义了很多支持机制,如unary_function、ptr_fun、mem_fun 等。请注意,所有这些都仅限于调整只接受一个或两个参数的可调用对象,因此它们在这个意义上是相当有限的。
现在我们有了decltype,可以用来推断可调用对象的返回类型、可变参数模板和完美转发以将任意数量的参数转发给函数等。C++11 之前的机制太麻烦了使用。
Stephan T Lavavej 在p0090r0 中首次提议在 C++17 中摆脱这些。论文相关摘录:
第一季度。你有什么建议?
* 删除所有提及result_type、argument_type、first_argument_type和second_argument_type...
* 删除由这些驱动的否定符not1()和not2()类型定义。
Q2。result_type等有什么问题?
A2。这些 C++98/03/TR1 时代的 typedef 早于decltype和完美的转发。以前,通用代码必须在适应函数对象之前从函数对象请求信息。现在,无需手动传达该信息。decltype取代result_type,因为编译器可以简单地报告使用特定参数调用函数对象的结果。并且完美转发取代了argument_type系列,因为适配器可以简单地获取/存储/转发任意参数。
如果您在论文中搜索 [func.wrap.func],它专门讨论了删除您所询问的 std::function 类型定义。
【讨论】: