我在cppreference上看到{C} 17中std::function::argument_type
被弃用了。它背后的原因是什么? ISO WG21论文提出了哪些建议?
答案 0 :(得分:17)
相关论文是P0005R4(这是投票进入标准草案的论文)和P0090R0(由P0005R4引用)。
来自P0090R0的引言:
Q2。 result_type等有什么问题?
A2。这些C ++ 98/03 / TR1时代的typedef早于decltype和perfect 转发。以前,通用代码必须从中请求信息 在调整它们之前的函数对象。现在,手动沟通 这些信息是不必要的。 decltype取代result_type, 因为编译器可以简单地报告调用的结果 具有特定参数的函数对象将是。而且完美 转发取代了argument_type系列,因为适配器可以 简单地获取/存储/转发任意参数。
事实上,这些typedef比无用更糟糕。他们'再 适得其反,因为许多可调用对象缺乏它们。功能 指向成员的指针和指针总是缺少它们。 ptr_fun() 最近,使用这些typedef包装了函数指针 删除(再次参见[1])。最重要的是,lambdas一直缺乏 这些typedef,它们是最重要的函数对象 所有。通用lambda更加不相容。
这意味着如果用户尝试编写通用代码 使用typedefs的result_type系列,它们的代码不会是通用的 - 它将无法处理lambdas,泛型lambda,函数指针等。
应该删除这些typedef,因为它们已经变得活跃 对现代代码有害。
答案 1 :(得分:7)
这些typedef存在的原因是not1
,bind1st
和朋友之类的东西,可以查询传递给它们的callables并检索调用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。