Avevo scritto funzioni di ordine superiore come questo:oggetti perfetti-spedizione richiamabili in funzioni di ordine superiore
template<typename F, typename... Args>
void doStuff(F f, Args&&... args)
{
// ...
f(std::forward<Args>(args)...);
// ...
}
O forse sostituire F f
con F&& f
.
Ma dopo aver saputo delle qualifiche di ref (ahi), le cose si sono complicate. Immaginate una classe funtore:
struct Foo {
void operator()(...) &;
void operator()(...) &&;
};
Poi i miei precedenti implementazioni di doStuff
sarà sempre e solo chiamare il metodo &
, dal momento che i parametri sono sempre lvalue.
Penso che il modo per risolvere questo è quello di implementare doStuff
in questo modo:
template<typename F, typename... Args>
void doStuff(F&& f, Args&&... args)
{
// ...
std::forward<F>(f)(std::forward<Args>(args)...);
// ...
}
Questo è anche il modo std::result_of
è possibly implemented. Quello che voglio sapere è che c'è qualche svantaggio in questa implementazione, cioè dovrei sostituire tutte le mie implementazioni HOF con esso?
Sembra buono fintanto che 'f' non verrà riutilizzato dopo. È possibile che 'operator()' abbia alcuni effetti collaterali che possono modificare i membri interni (spostati sui membri interni) di 'f' (se esiste). Non sono sicuro, però, non ci ho pensato ... Buona domanda. – Arunmu
@Arunmu Se (1) il metodo è sovraccarico su qualificatori ref e (2) il chiamante passa il functor come valore di rvalore, abbiamo una ragione sufficiente per credere che il chiamante intenda chiamare la versione '&&'. Stando così le cose, è probabilmente ragionevole perfezionare ogni occorrenza di 'f' in' doStuff' ... penso. –
Non vedo alcun problema con 'forward (f)' purché non si usi 'f' di nuovo all'interno di' doStuff' –
Praetorian