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

Vin*_*ent 18 c++ function deprecated language-lawyer c++17

我在cppreference上看到了std::function::argument_type在C++ 17 中被弃用的东西.它背后的原因是什么?ISO WG21论文提出了哪些建议?

cpp*_*ner 17

相关论文是P0005R4(投票成为标准草案的论文)和P0090R0(由P0005R4引用).

来自P0090R0的行情:

Q2.result_type等有什么问题?

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

事实上,这些typedef比无用更糟糕.它们适得其反,因为许多可调用对象缺乏它们.函数指针和指向成员的指针总是缺少它们.最近删除了包含带有这些typedef的函数指针的ptr_fun()(再次参见[1]).最重要的是,lambdas总是缺少这些typedef,它们是所有类型中最重要的函数对象.通用lambda更加不相容.

这意味着如果用户尝试使用typedef的result_type系列来编写通用代码,那么它们的代码将不是通用的 - 它将无法处理lambdas,泛型lambdas,函数指针等.

应删除这些typedef,因为它们对现代代码有害.


Pra*_*ian 7

这些typedef存在的原因是not1,bind1st和朋友一样,可以查询传递给它们的callable,并检索调用callable的结果类型,它的参数类型等.

为了使它们的使用适口性好,有很多支持机械,像unary_function,ptr_fun,mem_fun等方面也进行了定义.请注意所有这些仅限于使用一个或两个参数来调整callables,因此它们在这个意义上相当有限.

现在我们已经decltype可以使用它来推断出一个可调用的返回类型,可变参数模板和完美转发以将任意数量的参数转发给函数等等.预C++ 11机制使用起来过于繁琐.

Stephan T Lavavej首先提出在p0090r0中用 C++ 17 去除它们.该文件的相关摘录:

Q1.你在提议什么?
*删除的每提到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你所询问的typedef.