Ho visto su cppreference che std::function::argument_type
era deprecato in C++ 17. Qual è la ragione dietro a questo? E quale carta ISO WG21 lo stava proponendo?Perché std :: function :: argument_type è stato deprecato?
risposta
I documenti rilevanti sono P0005R4 (che è il documento votato nella bozza di standard) e P0090R0 (a cui fa riferimento P0005R4).
Citazioni da P0090R0:
Q2. Cosa c'è di sbagliato in result_type, ecc.?
A2. Questi typedefs dell'era C++ 98/03/TR1 predati decltype e perfetto inoltro . In precedenza, il codice generico doveva richiedere informazioni dagli oggetti funzione prima di adattarli. Ora, comunicare manualmente che informazioni non sono necessarie. decltype sostituisce result_type, perché il compilatore può semplicemente segnalare quale sarà il risultato della chiamata di un oggetto funzione con argomenti specifici. E l'inoltro perfetto sostituisce la famiglia argument_type, dal momento che gli adattatori possono semplicemente prendere/memorizzare/inoltrare argomenti arbitrari.
In realtà, questi typedef sono peggio che inutili. Sono controproducenti, perché a loro mancano molti oggetti chiamabili. Funzione puntatori e puntatori ai membri sono sempre mancati. ptr_fun(), che ha spostato i puntatori di funzione con questi typedef, è stato recentemente rimosso (si veda di nuovo [1]). Ancora più importante, i lambda sono sempre mancati a questi typedef e sono gli oggetti funzione più importanti di tutti. I lambda generici sono ancora più incompatibili.
Ciò significa che se un utente tenta di scrivere codice generico dal utilizzando la famiglia result_type di typedef, il loro codice non sarà generica - che sarà non riescono a gestire lambda, lambda generici, puntatori a funzione, ecc
Questi typedefs devono essere rimossi perché sono diventati attivamente dannosi per il codice moderno.
Il motivo esistono quei typedef sono quindi le cose come not1
, bind1st
e gli amici, potrebbe interrogare i callable passati a loro e recuperare il tipo del risultato di invocare il callable, i suoi tipi di argomenti ecc
Per rendere appetibile il loro uso, sono stati definiti anche molti macchinari di supporto, come unary_function
, ptr_fun
, mem_fun
ecc. Si noti come tutti questi sono limitati ad adattare callables prendendo solo uno o due argomenti, quindi sono piuttosto limitati in tal senso.
Ora che abbiamo decltype
che può essere utilizzato per dedurre un tipo di ritorno di callable, modelli variadic e inoltro perfetto per inoltrare un numero arbitrario di argomenti a funzioni, ecc. I meccanismi pre-C++ 11 sono troppo ingombranti da usare .
Stephan T Lavavej ha inizialmente proposto di sbarazzarsi di questi in C++ 17 in p0090r0. Estratti pertinenti dal documento:
Q1. Cosa stai proponendo?
* Rimozione di ogni menzione delresult_type
,argument_type
,first_argument_type
esecond_argument_type
...
* Rimozione dei negatorinot1()
enot2()
, che sono stati alimentati da questi typedef.
Q2. Cosa c'è che non va conresult_type
, ecc.?
A2. Questi typedefs dell'era C++ 98/03/TR1 predatidecltype
e inoltro perfetto. In precedenza, il codice generico doveva richiedere informazioni dagli oggetti funzione prima di adattarli. Ora, la comunicazione manuale di tali informazioni non è necessaria.decltype
sostituisceresult_type
, perché il compilatore può semplicemente segnalare quale sarà il risultato della chiamata di un oggetto funzione con argomenti specifici. E l'inoltro perfetto sostituisce la famigliaargument_type
, poiché gli adattatori possono semplicemente prendere/memorizzare/inoltrare argomenti arbitrari.
Se si cerca la carta per [func.wrap.func]
, si parla in particolare sulla rimozione delle std::function
typedef si sta chiedendo.