c++ function language-lawyer deprecated c++17

c++ - ¿Por qué std:: function:: argument_type ha quedado en desuso?



language-lawyer deprecated (2)

La razón por la que existen estas not1 tipo es que cosas como not1 , bind1st y amigos, pueden consultar los callables que se les pasan y recuperar el tipo de resultado de invocar el llamable, sus tipos de argumento, etc.

Para hacer que su uso sea aceptable, también se definieron muchas máquinas de soporte, como unary_function , ptr_fun , mem_fun , etc. Observe cómo todos estos se limitan a adaptar callables tomando solo uno o dos argumentos, por lo que son bastante limitados en ese sentido.

Ahora que tenemos un decltype que se puede usar para deducir el tipo de retorno de un invocador, las plantillas variad y el reenvío perfecto para reenviar un número arbitrario de argumentos a funciones, etc. los mecanismos anteriores a C ++ 11 son demasiado incómodos de usar.

Stephan T Lavavej propuso por primera vez deshacerse de estos en C ++ 17 en p0090r0 . Extractos relevantes del artículo:

Q1. Que propones
* Eliminando cada mención de result_type , argument_type , first_argument_type , y second_argument_type ...
* Eliminando los negadores not1() y not2() , que fueron alimentados por estas definiciones de tipo.

Q2. ¿Qué hay de malo en result_type , etc.?
A2. Estos decltype era C ++ decltype / TR1 son anteriores al tipo decltype y al reenvío perfecto. Anteriormente, el código genérico tenía que solicitar información de los objetos de función antes de adaptarlos. Ahora, la comunicación manual de esa información es innecesaria. decltype reemplaza result_type , porque el compilador puede simplemente informar cuál será el resultado de llamar a un objeto de función con argumentos específicos. Y el reenvío perfecto reemplaza a la familia argument_type , ya que los adaptadores pueden simplemente tomar / almacenar / reenviar argumentos arbitrarios.

Si busca en el documento [func.wrap.func] , se trata específicamente sobre la eliminación de los std::function que está preguntando.

He visto en cppreference que std::function::argument_type estaba en desuso en C ++ 17. ¿Cuál es la razón detrás de esto? ¿Y qué documento ISO WG21 proponía eso?


Los documentos relevantes son P0005R4 (que es el documento que se votó en el borrador de la norma) y P0090R0 (al que hace referencia P0005R4).

Citas de P0090R0:

Q2. ¿Qué hay de malo en result_type, etc.?

A2. Estos typedefs de la era C ++ 98/03 / TR1 son anteriores al tipo decl y al reenvío perfecto. Anteriormente, el código genérico tenía que solicitar información de los objetos de función antes de adaptarlos. Ahora, la comunicación manual de esa información es innecesaria. decltype reemplaza result_type, porque el compilador puede simplemente informar cuál será el resultado de llamar a un objeto de función con argumentos específicos. Y el reenvío perfecto reemplaza a la familia argument_type, ya que los adaptadores pueden simplemente tomar / almacenar / reenviar argumentos arbitrarios.

De hecho, estas typedefs son peores que inútiles. Son contraproducentes, porque muchos de los objetos que se pueden llamar carecen de ellos. Función de punteros y punteros a los miembros siempre han carecido de ellos. ptr_fun (), que envolvió los punteros de función con estas definiciones de tipo, se eliminó recientemente (ver [1] de nuevo). Lo más importante es que las lambdas siempre han carecido de estas definiciones de tipo, y son los objetos de función más importantes de todos. Las lambdas genéricas son aún más incompatibles.

Lo que esto significa es que si un usuario intenta escribir código genérico utilizando la familia de tipos de resultado result_type, su código no será genérico: no podrá manejar las lambdas, las genéricas, los punteros de función, etc.

Estos typedefs deben eliminarse porque se han vuelto activamente dañinos para el código moderno.