template<class...Fs>
void do_in_order(Fs&&...fs) {
int _[]={0, (std::forward<Fs>(fs)(), void(), 0)...};
(void)_;
}
nasconde il sintassi richiesta per eseguire un pacchetto di oggetti funzione nell'ordine da sinistra a destra.
Poi:
struct Bar {
template <class... Ts>
void foo() {
do_in_order([&]{
using T = Ts;
// code
}...);
}
};
e in un compilatore conforme, verrà eseguito il // code
con T
essere ogni tipo da sinistra a destra.
Si noti che alcuni compilatori che affermano di essere compilatori C++ 11 potrebbero non riuscire a compilare quanto sopra.
Il vantaggio di questa tecnica è che nasconde il brutto codice "espandi e valuta modelli" all'interno di una funzione con un nome chiaro. Scrivi do_in_order
una volta, e di solito è sufficiente per quasi ogni uso di quel trucco di espansione dell'array.
Ci sono due motivi importanti per utilizzare questo tipo di sintassi esoterica invece delle soluzioni ricorsive "più semplici".
In primo luogo, rende le cose più facili per l'ottimizzatore. Gli ottimizzatori a volte si arrendono dopo una pila di chiamate ricorsive.
In secondo luogo, la somma dei nomi delle lunghezze delle firme di funzione per le funzioni ricorsive tradizionali aumenta a O (n^2). Se si usano i tipi di aiuto, la lunghezza totale dei nomi è anche O (n^2). A meno che tu non stia attento, questo può causare il tempo di compilazione, il tempo di collegamento e le dimensioni binarie gonfie.
In C++ 1z ci sono piani per una sintassi di "piega" che potrebbe rendere meno esoteriche le parti esoteriche di cui sopra.
eh? 'pippo' non accetta argomenti. – MadScientist
Come svantaggio, richiede N passaggi ricorsivi per N tipi, e istanze tipi e funzioni il cui nome lunghezza somma a O (N^2). Fare quanto sopra con N modestamente grande causa una compilazione lenta, e può portare a un numero di caratteri binari se quei nomi non vengono rimossi dal compilatore. – Yakk